Javah 工具错误:找不到 hellojni 的类文件



我正在尝试从Windows 7操作系统上的命令行使用javah工具创建一个头文件,但我总是失败。

我遵循了不同的方法,甚至阅读了 oracle 的 javah 工具文档,但它们并没有帮助克服这个问题。

我的类文件(hellojni.class)和java文件(hellojni.java)都在D:驱动器的根目录中。

但是每当我运行javah工具时,它都会给我一个错误:

找不到 hellojni 的类文件

我也尝试提供类路径,但没有获得任何头文件。

我怀疑问题是您的类有一个包,并且您正在尝试使用类文件而不是包根目录从目录运行命令

Samhain 的例子之所以有效,是因为他的MyClass.java不包含任何包裹,而我怀疑你的包有。

例如,假设我们在 c:srccomexampleMyClass.java

package com.example;
public class MyClass {
    public native void myMethod();
}

转到命令行并执行以下操作:

c:srccomexample>javac MyClass.java
c:srccomexample>dir
 Directory of C:srccomexample
2015-02-23  03:17 PM    <DIR>          .
2015-02-23  03:17 PM    <DIR>          ..
2015-02-23  03:20 PM               219 MyClass.class
2015-02-23  03:17 PM                84 MyClass.java
c:srccomexample>javah MyClass
Error: Could not find class file for 'MyClass'.
c:srccomexample>cd c:src
c:src>javah com.example.MyClass
c:src>dir
 Directory of C:src
2015-02-23  03:18 PM    <DIR>          .
2015-02-23  03:18 PM    <DIR>          ..
2015-02-23  03:16 PM    <DIR>          com
2015-02-23  03:18 PM               449 com_example_MyClass.h

成功!

在尝试为 Java 本机接口 (JNI) 实现的两个步骤编译和生成 C/C++ 标头时,我也遇到了同样的问题(我怀疑这就是您尝试从文件名中执行的操作)。为我解决的是使用以下命令将两个步骤合并为一个:

javac YOUR_CLASS_FILE_NAME.java -h .

点 (.) 包括当前路径。此命令只能在 Java 8 中运行。

javah -classpath path_to_jars_or_classes com.my.package.MyClass .

如果使用 -verbose、javah -verbose -classpath path_to_jars_or_classes com.my.package.MyClass 运行,它将显示用于查找类的搜索路径。 您可以使用它来验证是否列出了您的目录 D:\。

参见 javah 文档

例: 文件名为 MyClass.java,内部类名为 MyClass。 没有错误。

C:>more MyClass.java
public class MyClass
{
   public static void doSomething(int b)
   {
      return;
   }
}
C:>javac MyClass.java
C:>javah -classpath C: MyClass
C:>dir *.h
 Volume in drive C has no label.
 Volume Serial Number is XXXX-XXXX
 Directory of C:
10/07/2013  11:46 AM               242 MyClass.h
               1 File(s)            242 bytes
               0 Dir(s)  X bytes free

我在安装了Java 8和Java 11(和默认)的Ubuntu 20.04上遇到了这样的问题:

$ javac -cp target/classes -d target/classes src/main/java/jni/JNIClass.java
$ javah -cp target/classes -d lib/ jni.JNIClass
Error: Could not find class file for 'jtni.JNIClass'.

看起来,javac指向Java 11实现,但javah仍然指向Java 8,因为javah不再包含在Java 11中。

Java 11 的解决方案是使用 javac 并请求它生成头文件:

$ javac -cp target/classes -h lib/ src/main/java/jni/JNIClass.java

假设您的类文件位于 D:/A 文件夹中cd 命令提示符到文件夹 A 并运行以下命令

D:/A>javah -classpath . classfilename

在这里.会将类路径设置为当前目录,javah 工具应该能够找到您的类文件。

在MacOS X上,它需要类路径变量。如果也可以在其他平台上进行验证,这可能是解决方案。

$ javah -verbose Article.HelloJNICpp
$ javah -verbose -classpath ./ Article.HelloJNICpp
[Creating file RegularFileObject[Article_HelloJNICpp.h]]
$ 

如果您使用的是 eclipse:将 -classpath PATH_OF_PACKAGE_TOP 附加到 javah CLASSNAME 中

示例:javah -classpath . com.byf.test.JNI

my tree : `
.
├── com
│   └── byf
│       └── test
│           └── JNI.java
└── libcall.so`

result:`
    byf@byf-Ubuntu:~/code/workspace_eclipse_java/JAVA_YF/src$ javah -classpath . com.byf.test.JNI
    byf@byf-Ubuntu:~/code/workspace_eclipse_java/JAVA_YF/src$ ls
    com  com_byf_test_JNI.h  libcall.so
    byf@byf-Ubuntu:~/code/workspace_eclipse_java/JAVA_YF/src$ cat com_byf_test_JNI.h 
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_byf_test_JNI */
    #ifndef _Included_com_byf_test_JNI
    #define _Included_com_byf_test_JNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_byf_test_JNI
     * Method:    add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_com_byf_test_JNI_add
      (JNIEnv *, jclass, jint, jint);
    #ifdef __cplusplus
    }
    #endif
    #endif
    `

最新更新