无法使用 JDK11 javac 仅针对变量 class 文件创建 JNI header 文件
Can not create JNI header file with JDK11 javac for variable only class file
我想将我的 java 程序从 JDK8 迁移到 JDK11。
我解决了由 JDK11 中删除的 API 导致的构建错误。
但是,我遇到了与 JNI 相关的问题。
为了解释这个问题,假设我们有以下 java 文件。
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
}
可以看到,它只有一个int变量,并没有定义方法。
当我用 JDK8 生成 JNI header 文件时,我执行以下步骤。
1) 编译
javac -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
2) 生成 header
javah -jni -d $OUTPUT_DIR/jni -cp ./$OUTPUT_DIR mypkg.JNITest
然后,它会生成一个 header 文件 (mypkg_JNITest.h),如下所示:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypkg_JNITest */
#ifndef _Included_mypkg_JNITest
#define _Included_mypkg_JNITest
#ifdef __cplusplus
extern "C" {
#endif
#undef mypkg_JNITest_X_MINOR_MASK
#define mypkg_JNITest_X_MINOR_MASK 1L
#ifdef __cplusplus
}
#endif
#endif
如您所知,JDK11 不再支持 javah。
我们必须使用 'javac -h' 来代替它。
所以,我编译了 java 文件,如下所示。
javac -h ./$OUTPUT_DIR/jni -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
编译成功,但是没有生成jni文件。
为了测试它是否在具有本机方法时生成 jni 文件,我尝试了以下 java 文件。
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
public native int intMethod(int n);
}
然后,它成功生成了如下所示的JNI文件。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypkg_JNITest */
#ifndef _Included_mypkg_JNITest
#define _Included_mypkg_JNITest
#ifdef __cplusplus
extern "C" {
#endif
#undef mypkg_JNITest_X_MINOR_MASK
#define mypkg_JNITest_X_MINOR_MASK 1L
/*
* Class: mypkg_JNITest
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_mypkg_JNITest_intMethod
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
最后一个问题:
有没有办法用 JDK11 的 javac 为一个只定义了一个 'static final int' 变量的 java 文件生成一个 JNI 文件?
只需用 @Native
标记字段
package mypkg;
import java.lang.annotation.Native;
public class JNITest {
@Native
static final int X_MINOR_MASK = 1;
}
我想将我的 java 程序从 JDK8 迁移到 JDK11。 我解决了由 JDK11 中删除的 API 导致的构建错误。
但是,我遇到了与 JNI 相关的问题。
为了解释这个问题,假设我们有以下 java 文件。
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
}
可以看到,它只有一个int变量,并没有定义方法。
当我用 JDK8 生成 JNI header 文件时,我执行以下步骤。
1) 编译
javac -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
2) 生成 header
javah -jni -d $OUTPUT_DIR/jni -cp ./$OUTPUT_DIR mypkg.JNITest
然后,它会生成一个 header 文件 (mypkg_JNITest.h),如下所示:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypkg_JNITest */
#ifndef _Included_mypkg_JNITest
#define _Included_mypkg_JNITest
#ifdef __cplusplus
extern "C" {
#endif
#undef mypkg_JNITest_X_MINOR_MASK
#define mypkg_JNITest_X_MINOR_MASK 1L
#ifdef __cplusplus
}
#endif
#endif
如您所知,JDK11 不再支持 javah。 我们必须使用 'javac -h' 来代替它。
所以,我编译了 java 文件,如下所示。
javac -h ./$OUTPUT_DIR/jni -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
编译成功,但是没有生成jni文件。
为了测试它是否在具有本机方法时生成 jni 文件,我尝试了以下 java 文件。
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
public native int intMethod(int n);
}
然后,它成功生成了如下所示的JNI文件。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypkg_JNITest */
#ifndef _Included_mypkg_JNITest
#define _Included_mypkg_JNITest
#ifdef __cplusplus
extern "C" {
#endif
#undef mypkg_JNITest_X_MINOR_MASK
#define mypkg_JNITest_X_MINOR_MASK 1L
/*
* Class: mypkg_JNITest
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_mypkg_JNITest_intMethod
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
最后一个问题: 有没有办法用 JDK11 的 javac 为一个只定义了一个 'static final int' 变量的 java 文件生成一个 JNI 文件?
只需用 @Native
package mypkg;
import java.lang.annotation.Native;
public class JNITest {
@Native
static final int X_MINOR_MASK = 1;
}