javac";“无源文件”;当使用-h选项时

javac";“无源文件”;当使用-h选项时,java,c,java-native-interface,header-files,Java,C,Java Native Interface,Header Files,我正在尝试使用JNI和JDK9。我有一个类NativeTest.java,如下所示: public class NativeTest { static { System.loadLibrary("hello"); } private native void sayHello(); public static void main(String[] args) { new NativeTest().sayHello();

我正在尝试使用JNI和JDK9。我有一个类
NativeTest.java
,如下所示:

public class NativeTest {

    static {
        System.loadLibrary("hello");
    }

    private native void sayHello();

    public static void main(String[] args) {
        new NativeTest().sayHello();
    }
}
我编译该类,然后使用
javah NativeTest
生成头文件

在发出
javah
时,我收到以下警告:

Warning: The javah tool is planned to be removed in the next major
JDK release. The tool has been superseded by the '-h' option added
to javac in JDK 8. Users are recommended to migrate to using the
javac '-h' option; see the javac man page for more information.
我知道距离下一个主要的JDK发布还有一段时间,但我想我现在应该开始习惯这个新选项了

因此,在尝试
javac-h NativeTest.java
(以及其他变体,如
NativeTest
NativeTest.class
,等等)时,我不断遇到以下错误:

javac:没有源文件

我无法在网上找到任何帮助,可能是因为此功能相对较新,并且在手册页中找不到有关此新的
-h
选项的任何信息


还有人试过这个吗?我缺少什么?

在Java8中,您必须执行生成类文件的中间步骤才能获得C头文件

假设你有以下结构

recipeNo001
├── Makefile
├── README.md
├── c
│   └── recipeNo001_HelloWorld.c
├── java
│   └── recipeNo001
│       └── HelloWorld.java
├── lib
└── target
在Java(JDK9之前)中,您必须编译类并将javah与编译的源代码一起使用

> export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_11)
> ${JAVA_HOME}/bin/javac -d target java/recipeNo001/*.java
> ${JAVA_HOME}/bin/javah -d c -cp target recipeNo001.HelloWorld
# -d c       -> put generated codes inside c directory
# -cp target -> compiled classes are inside target dir
在Java9中,您可以将
javac-h
与Java源代码一起使用

> export JAVA_HOME=$(/usr/libexec/java_home -v 9)
> ${JAVA_HOME}/bin/javac -h c java/recipeNo001/HelloWorld.java
# -h c       -> create header file inside c directory

我发现的解决方案是,我没有指定
javac
应该放置头文件的目录


执行
javac-h。java工作正常。

javah工具已被“javac-h”特性取代。我们应该能够在Java编译步骤中使用普通的Java编译器(Java8+中带有-h标志)来输出这些文件

用法: -h目录 指定放置生成的本机头文件的位置

指定此选项时,将为包含本机方法或具有一个或多个用java.lang.annotation.native注释的常量的每个类生成本机头文件。如果类是包的一部分,那么编译器会将本机头文件放在反映包名的子目录中,并根据需要创建目录


javac-h目录名NativeTest.java将解决这个问题

啊,没关系,我找到了。您需要指定放置头文件的目录<代码>javac-h。java
。我将把这个问题留待以后,以防其他人遇到同样的疏忽。你可以回答自己的问题,并将其标记为已接受的答案。这将减少未回答问题的数量。请注意,这只会将生成的
.class
文件扔到其他地方,很可能会弄乱您的源代码树。(至少对于openjdk版本13 javac)。