Unsatisfiedlinkerror When Using Jni

C++ JNI UnsatisfiedLinkError

Your Java class name and method name contain underscores, which goes against the naming convention.

If you insist on keeping them, you need to change the name of your C++ function to Java_Java_1List_init_1list. Note the 1s before List and list, which tells the linker to interpret the preceeding underscore as a literal underscore character instead of a naming separator.

How to resolve UnsatisfiedLinkError when using JNI with packages?

It looks like you have the wrong name from your library file (libSample.so).

If you use:

System.loadLibrary("Sample");

The JVM will map this name to a platform specific file name to try and load. On Linux that is libSample.so, on Windows that is Sample.dll, but on OS X it's something else.

You can find out which name your library file should have by looking at the output of:

System.mapLibraryName("Sample");

Called on the target platform.

After that, you can use that as the name of your library file.

JNI UnsatisfiedLinkError without wrong method names and with library path specified

It turns out that the problem is due to some naming convention on unix/linux platforms! When using:
System.loadLibrary("hello");
the file should not be named hello.so! Instead, the name should be libhello.so. On Windows, use hello.dll. I'm surprised that this issue is not mentioned in IBM's JNI tutorial: http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html

I'm not sure what the rationality behind this issue is. Why would you load a library "hello" which should be named libhello.so on your filesystem (instead of hello.so)?

UnsatisfiedLinkError with JNI

Seems like things worked with using the correct naming scheme for OS X libhello.dylib and the -shared option.

gcc -I /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/darwin/  -o libhello.dylib -shared HelloWorldImp.c

java.lang.UnsatisfiedLinkError when using JNI on ubuntu

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

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...

Here's your new Makefile:

CPPFLAGS:=-I"${JAVA_HOME}/include" -I"${JAVA_HOME}/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)


Related Topics



Leave a reply



Submit