-
Hello. I'm trying to create and test a JNI library using pre-built binaries.
To simplify the code, I removed almost everything inside the sayHello function in the .cpp file and returned the input jstring.
The jni header file is properly generated in build>>generated>>jni-headers and matches the implementation in the .cpp. The java class Loader uses the NativeLoader to load the library "jni-greeter" without any problem.
Any idea of what I might be missing would be really appreciated. Thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 1 reply
-
The problem is being unable to locate the shared library. In the process of renaming, I'm assuming the project name may have changed as well which cause the final library name to be wrong. You can double check the hypothesis by looking inside the |
Beta Was this translation helpful? Give feedback.
-
Inside the For my sample code, I'm using the On the other hand, if I change the name of the library in the
I would think that in the initial code it is finding the shared library, but maybe not the implementation of the native function or the jni header file? |
Beta Was this translation helpful? Give feedback.
-
Hmmm, good point. Could you share your sample as it's failing with the unsatisfied link error? It has to be something simple :-( In the past, I did spend a lot of time tracking trivial issues as JNI doesn't give good error messages. Given the mention of |
Beta Was this translation helpful? Give feedback.
-
I'm working in Ubuntu 18.04. For the JDK and gradle version:
I have created a repository with my sample version here. Btw, I printed the Java path while testing and it was pointing to the correct location, so Thanks a lot for taking your time to help me solve this problem! |
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay in the response. So the issue is actually with how exported methods are named. The error message is correct, I simply misinterpreted it. The prebuilt binaries in the example are built for
The encoding here is how JNI expects the native methods to be exported. The generated JNI header from The unsatisfied link exception comes from the fact the function for the native method was not found. Either you recompile the prebuilt binaries or keep the original name. In a real project, you would need to make sure the native method on the Java side matches the exported methods from the prebuilt binaries. I understand the confusion and I should add more documentation around troubleshooting JNI-related issues. I hope that help you progress in your experimentation. |
Beta Was this translation helpful? Give feedback.
-
I saw that you also have the native code in there which may be what you were trying to compile. The sample force the usage of the prebuilt binaries by overwriting the
To compile the
2- Change the shared library baseName. Prepend the
In the specific version you are using, 3- Remove the That will add the C++ language capability to the project, e.g. C++ sources compilation. It will also force the shared library name to align with the |
Beta Was this translation helpful? Give feedback.
-
I hope you don't mind converting the issue into a discussion which better suits the original request. I'm open for any feedback you may have on this. |
Beta Was this translation helpful? Give feedback.
Sorry for the delay in the response. So the issue is actually with how exported methods are named. The error message is correct, I simply misinterpreted it. The prebuilt binaries in the example are built for
com.example.greeter.Greeter#sayHello
. If we list the symbols on the prebuilt binaries, we can see the following (for macOS):The encoding here is how JNI expects the native methods to be exported. The generated JNI header from
javac
usually takes care of the for you. For example, the JNI signature for the rename you performed is:JNIEXPORT jstring JNICALL Java_com_example_loader_Loader_sayHello (JNIEnv *, jobject, …