Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not create JNI header file with JDK11 javac for variable only class file

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?

like image 651
Geobongpapa Avatar asked Mar 10 '20 14:03

Geobongpapa


1 Answers

Just mark the field with @Native

package mypkg;

import java.lang.annotation.Native;

public class JNITest {
    @Native
    static final int X_MINOR_MASK = 1;
}
like image 153
Holger Avatar answered Sep 23 '22 23:09

Holger