I have a Java code ServiceTest.java that invokes JNI code buildCache() to build the cache. This codes compiled and exceuted correctly on Ubuntu; however, on centos I compiled and exceuted and got this error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.test.app.ServiceTest.buildCache()V
at com.test.app.ServiceTest.buildCache(Native Method)
at com.test.app.ServiceTest.<init>(ServiceTest.java:15)
at com.test.app.ServiceTest.main(ServiceTest.java:47)
Looks like, it was able to load the so file, but it is not able to invoke the method.
ServiceTest.java
public class ServiceTest{
static {
System.loadLibrary("cacheService");
}
public ServiceTest() {
buildCache();
}
private native void buildCache();
}
libcacheService.so is placed in /usr/local/lib64. I have gcc 9 and jdk 1.8
and have set LD_LIBRARY_PATH=/usr/local/ and export $LD_LIBRARY_PATH.
Any idea on how to debug?
******Adding below simple testcode******
1.
public class Test{
static {
System.loadLibrary("greet");
}
Test(){
}
public static void main(String...s){
Test t = new Test();
System.out.println(t.greetings());
}
private native String greetings();
}
- javah Test -> Test.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> /* Header for class Test */
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: greetings
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_Test_greetings
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
- Greetings.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>
#include "Test.h"
using namespace std;
class Test{
JNIEXPORT jstring JNICALL Java_Test_greetings(JNIEnv *env, jobject thisObject){
jstring result = env->NewStringUTF("hi from JNI");
return result;
}
};
-
g++ --std=c++17 -g -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared -o greetings.so Greetings.cpp
-
$JAVA_HOME/bin/java -Djava.library.path=/lib64 Test
-
again same issue
Exception in thread “main” java.lang.UnsatisfiedLinkError: Test.greetings()Ljava/lang/String;
at Test.greetings(Native Method)
at Test.main(Test.java:13)
With same GCC 9 and jdk 1.8
2
Answers
The problem is that native library does not define a method that matches the signature of the Java
native
method; i.e. method name or signature in the JNI code is wrong … or maybe it isn’t a JNI native library at all.Your
Greetings.cpp
should not includeclass Test
:Then, the Java statement
System.loadLibrary("greet");
expects to find alibgreet.so
in itsjava.library.path
, so compile it as follows:Next, verify that the symbol is named exactly like the function, ie
nm libgreet.so | grep Java_Test_greetings
should produce output like the following:Finally, run your Java program with the correct
java.library.path
.