UnsatisfiedLinkError when using JNI?
I want to call a C program from Java program using JNI in linux ubuntu. I am new to this and I have tried the sample program given in http://www.ibm.com/developerworks/java/tutorials/j-jni/section2.html . I have already created the .java, .h , .c and .so files. But when i tried to run the program I am getting the following error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample1 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738) at java.lang.Runtime.loadLibrary0(Runtime.java:823) at java.lang.System.loadLibrary(System.java:1028) at Sample1.main(Sample1.java:13)
It is missing something called «Sample1». Ensure the shared object is built and in the indicated path.
@poonam Hoshi: Please write the steps used in creating the sharelibrary and command line/LD_LIBRARY_PATH used to pass the library to jvm..
2 Answers 2
This exception is indicating that the .so is not available to the JVM.
Adding the directory where the .so exists to the LD_LIBRARY_PATH will resolve this. If the .so depends on other .so libraries the directories where these .so exist will also need added to LD_LIBRARY_PATH .
I tried setting the library path but it is still not working. My ubuntu version is Ubuntu 10.04.4 LTS. I just learned from some other site that in this version of ubuntu LD_LIBRARY_PATH doesnot work anymore.Please help resolving this. and Thanks for the help.
I’ve just tried to get the same sample to work on my CentOS and got the same error as you. As already answered, JVM failed to find the so file needed. I succeeded to get it to work by following the steps below using gcc:
$ javac Sample1.java $ javah Sample1 $ # Include paths must also be specified using -I option in the following gcc command line! $ gcc -shared -I. snip. Sample1.c -o libSample1.so $ # Library path for libSample1.so must also be specified! $ java -Djava.library.path=. path/to/libSample1.so. Sample1
If you omit the «lib» prefix of the shared library, JVM fails to find it for some reason. I don’t know why. I am not familiar with the naming convention of shared libraries in Linux.
I hope this post could help.
Error when using JNI on ubuntu: java.lang.UnsatisfiedLinkError: no . in java.library.path
I know there are similar questions on this topic but none of the answers could solve my problem: I have a java file:
class hjni < static < System.loadLibrary("hjni"); >private native void print(); public static void main(String[] args) < new hjni().print(); >>
javac hjni.java javah -jni hjni
#include #include #include "hjni.h" JNIEXPORT void JNICALL Java_hjni_print(JNIEnv *env, jobject obj)
g++ -fPIC -shared -I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include/linux hjni.cpp -o hjni.so
java -Djava.library.path=. hjni
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hjni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1889) at java.lang.Runtime.loadLibrary0(Runtime.java:849) at java.lang.System.loadLibrary(System.java:1088) at hjni.(hjni.java:4)
java.library.path = /usr/java/packages/lib/amd64 /usr/lib/x86_64-linux-gnu/jni /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /usr/lib/jni /lib /usr/lib
cd /usr/java/packages/lib/amd64 bash: cd: /usr/java/packages/lib/amd64: No such file or directory
/usr/lib/jvm/java-7-openjdk-amd64/lib/amd64/jli
export LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-amd64/lib/amd64/jli
the path is successfully added as long as the terminal is open. If I close the terminal and reopen it, then the added path is no longer there. I also copied hjni.so to the jli folder but I got the same linking error.
java.lang.UnsatisfiedLinkError in Linux
I’ve managed to get into a linux machine to try the HotKey library suggested in this answer. I’ve compiled the sample code and now I run the program and I’ve got the following message:
[oracle@machine jxgrabkey-0.2.1_i386]$ java -classpath lib/JXGrabKey.jar:Example JXGrabKeyTest Exception in thread "main" **java.lang.UnsatisfiedLinkError:** /home/oracle/javasample/jxgrabkey-0.2.1_i386/lib/libJXGrabKey.so: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /home/oracle/javasample/jxgrabkey-0.2.1_i386/lib/libJXGrabKey.so) at java.lang.Runtime._load(libgcj.so.7rh) at java.lang.Runtime.load(libgcj.so.7rh) at java.lang.System.load(libgcj.so.7rh) at JXGrabKeyTest.main(JXGrabKeyTest.java:17)
I know how to handle this in Windows ( just by adding the DLL to the PATH env var ) but I’m not that sure about linux. I’ve read something about LD_LIBRARY_PATH and some other env vars but I can make it work. Any advice? EDIT After the support from mmyers to indentify the problem and reading this thread and this other. I can tell: My system is: Linux 2.6.18-53.el5 My GCC version(s) is ( are) : gcc-c++-4.1.2-14.el5 gcc-gfortran-4.1.2-14.el5 libgcc-4.1.2-14.el5 gcc-4.1.2-14.el5 The problems is I require gcc 4.2.0 Aaand apparently there is no gcc 4.2.0 for my system. I guess I would have to wait for it to come or the author recompile it in a previous version. mmyers, thanks a lot for your help.
What is the cause of an UnsatisfiedLinkError?
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
It is an error related to JNI. loadJacobLibrary is trying to load the native library called jacob-1.14.3-x86 and it is not found on the path defined by java.library.path. This path should be defined as a system property when you start the JVM. e.g.
On Windows, the actual native library file will be called jacob-1.14.3-x86.dll while on Linux it would be called libjacob-1.14.3-x86.so
i would add that path should not end with slash/backslash — just with the name of the directory (oh god I was making this mistake)
You need the jacob-1.14.3-x86 library on your java library path.
On windows, this would be jacob-1.14.3-x86.dll.
This is a binary file which is used by java to run native methods. It’s probably required by some library (jar) you’re using.
In here you can see not only a jar, but also the binary required by the jar. Pick the one for your platform.
There are two things that cause UnsatisfiedLinkError. One is when System.loadLibrary() fails to load the library, the other is when the JVM fails to find a specific method in the library. The text of the error message itself will indicate which is the case.
The error which you describe clearly cannot find the library at all. As the others have said, include it in your Java library path.
The other error—when the library can be found but the method within the library is not found—looks as follows:
java.lang.UnsatisfiedLinkError: myObject.method([Ljava/lang/Object;)V
In this case you either have the wrong method name, or will have to go back and add the method and recompile the code.
java.lang.UnsatisfiedLinkError when using JNI on ubuntu
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 java.library.path=.:/home/mancook/cook/work/StSoftware/src/java/StTestJni/tutor01_HelloJNI:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
Exception in thread «main» java.lang.UnsatisfiedLinkError: no libHelloJNI in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at HelloJNI.main(HelloJNI.java:22)
make: *** [run] Error 1
I have googled internet for this problem and find that it is an OLD question. But I CANNOT find any method to fix my problem!! Hope someone can help me. Thanks in advance.
Could you also paste your native file, the HelloJNI.c ? That would make it simpler for people to reproduce this.
#include #include #include «HelloJNI.h» JNIEXPORT void JNICALL Java_HelloJNI_sayHello (JNIEnv * env, jobject thisObj)
Yes you can edit your question. There’s a grey «edit» text below your question. Everybody can edit your question. That’s what StackOverflow is designed for.
1 Answer 1
You need -Djava.library.path=. in the Makefile, and you need to load the library with System.loadLibrary(«HelloJNI»); — no lib prefix, no .so suffix. The prefix and suffix are handled by Java — think of it, naming scheme on Windows is different (stupid but fact). And beware of the pitfall that you have System.loadLibrary() twice in your code, if you change only one of them, it will still fail. That one actually had cost me a few minutes 😛
P.S.: I suggest a few changes to your Makefile. I would use $(RM) instead of rm . Goals which are not files should be declared .PHONY . Variables which do not refer to automatic variables can be assigned with := instead of = . I would use a separate step for creating the .so from the .o file. I would use a pattern rule for compiling Java, like %.class: %.java . I would use a pattern rule for creating the header file, like %.h: %.class . The -I stuff should be in CPPFLAGS not CFLAGS because it’s for the preprocessor. The -shared should then go into LDFLAGS and so on.
CPPFLAGS:=-I"$/include" -I"$/include/linux" JNI_LIB:=libHelloJNI.so JNI_OUT:=$(JNI_LIB) HelloJNI.o HelloJNI.h HelloJNI.class CFLAGS:=-fPIC LDFLAGS:=-shared .PHONY: all all: $(JNI_OUT) %.h: %.class javah -jni HelloJNI $(JNI_LIB): HelloJNI.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ HelloJNI.o: HelloJNI.c HelloJNI.h %.class: %.java javac HelloJNI.java .PHONY: run run: java -Djava.library.path=. HelloJNI .PHONY: clean clean: $(RM) $(JNI_OUT)