Apache ant javah 任务不适用于 jdk 10+



我们正在从 jdk 1.8 转向 jdk13。在我们的构建中.xml我们有

<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javah class="com.zimbra.znative.IO" outputfile="${build.dir}/IO.h" classpathref="build.class.path"/>
</target>

但是java10+不再支持javah,所以我发现我们可以在这里使用javac"nativeheaderdir"来实现这一点 - https://ant.apache.org/manual/Tasks/javac.html#nativeheaderdir

所以我尝试将上面的javah任务转换为javac,如下所示

<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" nativeHeaderDir="${build.dir}" classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java"  />
</target>

现在丢失的javah错误消失了,但我没有看到在我的构建目录中生成的IO.h文件。 谁能帮我,怎么做?非常感谢您的帮助,谢谢。

注意:目录 src/java/com/zimbra/znative 大约有 5-6 个.java文件。我只提到了一个 1 个文件的示例。

我看不出有明显的方法来说服javac任务这样做。nativeHeaderDir=生成标头,但不会像您找到的那样连接。

javac 后解决方法可能如下所示 - 使用 Ant<concat>任务将每个类的标头合并到单个文件中:

<concat destfile="IO.h">
<header>/* DO NOT EDIT THIS FILE - it is machine generated */
#include &lt;jni.h&gt;
</header>
<concat destfile="IO.h">
<fileset dir="${build.dir}" includes="*.h" />
<filterchain>
<linecontainsregexp negate="true">
<regexp pattern="(#include .jni.h.)|(DO NOT EDIT THIS FILE - it is machine generated)" />
</linecontainsregexp>
</filterchain>
</concat>
</concat>

基本思想很简单:找到javac生成的所有头文件,将它们连接成一个具有所需名称的头文件。 (可选(在此过程中,去除重复的 #include 和注释行。 结果应该看起来与 JDK 8 javah 生成的标头相同。

通过以下更改,我能够创建头文件。但是生成的文件名是"com_zimbra_znative_IO.h"。它应该是"IO.h">

<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java/com/zimbra/znative" destdir="${build.dir}"  nativeHeaderDir="${build.dir}" classpathref="build.class.path"
includes="IO.java"                                                                                                      
excludes="Process.java,ProcessorUsage.java,ResourceUsage.java,Util.java,ProxyInfo.java" />
</target>

使用 javac 任务从 ant 生成头文件应该与生成的类文件一起。因此,如果相应的类文件已经可用并且源文件中没有更改(换句话说,编译的类修改时间高于 java 源文件(,那么 javac ant 任务将不会对该类文件执行任何操作,包括本机头文件生成。

你必须执行一些检查,

  1. 您的srcdir属性是否指向启动包的正确目录。(例如,您的类名是com.zimbra.znative.MyClass并且文件路径是src/java/com/zimbra/znative/MyClass.java那么您的srcdir应指向src/java
  2. 提供生成已编译类文件的位置destdir,否则它将在srcdir中生成。
  3. 通常包括不需要,如果你想生成所有头文件,所有类在你的srcdir中都有本机方法
<target name="generate-native-headers" depends="compile,resolve" description="Java to Native">
<javac srcdir="src/java" nativeHeaderDir="${build.dir}" destdir="${build.classes}"
classpathref="build.class.path" includes="src/java/com/zimbra/znative/IO.java"  />
</target>

在运行 ant 之前,请确保IO.class文件不存在,或者源.java文件比现有类文件最近发生了更改。 然后看到它将生成类文件和头文件。头文件应位于${build.dir}

最新更新