Issue
I would like to migrate my java program from JDK8 to JDK11. I resolved build errors caused by APIs removed in JDK11.
But, I got JNI related problem.
To explain about the problem, let's assume that we have the following java file.
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
}
As you can see, it has only one int variable, and no method is defined.
When I generate JNI header file with JDK8, I do the following steps.
1) Compile
javac -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
2) generating header
javah -jni -d $OUTPUT_DIR/jni -cp ./$OUTPUT_DIR mypkg.JNITest
Then, it generates a header file(mypkg_JNITest.h) like below:
/* 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
As you know, JDK11 does not support javah any more. We have to use 'javac -h' instead of it.
So, I compiled the java file like below.
javac -h ./$OUTPUT_DIR/jni -sourcepath ./mypkg -d $OUTPUT_DIR ./mypkg/JNITest.java
It compiled well, but no jni file generated.
To test if it generate jni file when it has a native method, I tried with the following java file.
package mypkg;
public class JNITest {
static final int X_MINOR_MASK = 1;
public native int intMethod(int n);
}
Then, it successfully generated a JNI file like below.
/* 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
Final Question: Is there a way to generate a JNI file with javac of JDK11 for a java file which just defines a 'static final int' variable?
Solution
Just mark the field with @Native
package mypkg;
import java.lang.annotation.Native;
public class JNITest {
@Native
static final int X_MINOR_MASK = 1;
}
Answered By - Holger
Answer Checked By - Marilyn (JavaFixing Volunteer)