java.lang.UnsatisfiedLinkError 在 ubuntu 上使用 JNI 时
java.lang.UnsatisfiedLinkError when using JNI on ubuntu
java.lang.UnsatisfiedLinkError 使用 JNI 时。
我的测试环境:
Ubuntu 12.04/64-bit
JDK 1.7
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5)
这是我的 java 来源:
public class HelloJNI {
static {
//System.loadLibrary("libHelloJNI");
}
private native void sayHello() ;
public static void main(String[] args){
//System.getProperties().list(System.out);
String lib_path = System.getProperty("java.library.path");
System.out.println("java.library.path=" + lib_path);
System.loadLibrary("libHelloJNI");
HelloJNI myJNI = new HelloJNI();
myJNI.sayHello();
}
}
这是我的 C 源代码:
#include <stdio.h>
#include "HelloJNI.h"
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj)
{
puts("Hello Momo. This is C code.");
return;
}
这是我的 Makefile:
JNI_INC=-I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux"
JNI_LIB=libHelloJNI.so
JNI_OUT=$(JNI_LIB) HelloJNI.h HelloJNI.class
CFLAGS= $(JNI_INC) -fPIC -shared
all: $(JNI_OUT)
HelloJNI.h: HelloJNI.class
javah -jni HelloJNI
$(JNI_LIB): HelloJNI.c HelloJNI.h
gcc $(CFLAGS) -o $@ HelloJNI.c
HelloJNI.class: HelloJNI.java
javac HelloJNI.java
run:
java HelloJNI
#java -Djava.library.path=. HelloJNI
clean:
rm $(JNI_OUT)
当我 运行 java 应用程序时,出现老问题:
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
我在互联网上搜索了这个问题,发现这是一个老问题。但是我无法找到任何方法来解决我的问题!!希望可以有人帮帮我。 提前致谢。
Makefile中需要-Djava.library.path=.
,加载库时需要System.loadLibrary("HelloJNI");
——没有lib
前缀,没有.so
后缀。前缀和后缀由 Java 处理 - 想一想,Windows 上的命名方案是不同的(愚蠢但事实)。并且要注意你的代码中有两次 System.loadLibrary()
的陷阱,如果你只更改其中一个,它仍然会失败。那个实际上花了我几分钟时间 :P
P.S.: 我建议对您的 Makefile 进行一些更改。我会使用 $(RM)
而不是 rm
。不是文件的目标应该声明 .PHONY
。不涉及自动变量的变量可以用 :=
代替 =
赋值。我将使用单独的步骤从 .o
文件创建 .so
。我会使用模式规则来编译 Java,例如 %.class: %.java
。我会使用模式规则来创建头文件,例如 %.h: %.class
。 -I
应该在 CPPFLAGS
而不是 CFLAGS
中,因为它用于预处理器。 -shared
然后应该进入 LDFLAGS
等等...
这是你的新 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)
java.lang.UnsatisfiedLinkError 使用 JNI 时。
我的测试环境:
Ubuntu 12.04/64-bit
JDK 1.7
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5)
这是我的 java 来源:
public class HelloJNI {
static {
//System.loadLibrary("libHelloJNI");
}
private native void sayHello() ;
public static void main(String[] args){
//System.getProperties().list(System.out);
String lib_path = System.getProperty("java.library.path");
System.out.println("java.library.path=" + lib_path);
System.loadLibrary("libHelloJNI");
HelloJNI myJNI = new HelloJNI();
myJNI.sayHello();
}
}
这是我的 C 源代码:
#include <stdio.h>
#include "HelloJNI.h"
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj)
{
puts("Hello Momo. This is C code.");
return;
}
这是我的 Makefile:
JNI_INC=-I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux"
JNI_LIB=libHelloJNI.so
JNI_OUT=$(JNI_LIB) HelloJNI.h HelloJNI.class
CFLAGS= $(JNI_INC) -fPIC -shared
all: $(JNI_OUT)
HelloJNI.h: HelloJNI.class
javah -jni HelloJNI
$(JNI_LIB): HelloJNI.c HelloJNI.h
gcc $(CFLAGS) -o $@ HelloJNI.c
HelloJNI.class: HelloJNI.java
javac HelloJNI.java
run:
java HelloJNI
#java -Djava.library.path=. HelloJNI
clean:
rm $(JNI_OUT)
当我 运行 java 应用程序时,出现老问题:
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
我在互联网上搜索了这个问题,发现这是一个老问题。但是我无法找到任何方法来解决我的问题!!希望可以有人帮帮我。 提前致谢。
Makefile中需要-Djava.library.path=.
,加载库时需要System.loadLibrary("HelloJNI");
——没有lib
前缀,没有.so
后缀。前缀和后缀由 Java 处理 - 想一想,Windows 上的命名方案是不同的(愚蠢但事实)。并且要注意你的代码中有两次 System.loadLibrary()
的陷阱,如果你只更改其中一个,它仍然会失败。那个实际上花了我几分钟时间 :P
P.S.: 我建议对您的 Makefile 进行一些更改。我会使用 $(RM)
而不是 rm
。不是文件的目标应该声明 .PHONY
。不涉及自动变量的变量可以用 :=
代替 =
赋值。我将使用单独的步骤从 .o
文件创建 .so
。我会使用模式规则来编译 Java,例如 %.class: %.java
。我会使用模式规则来创建头文件,例如 %.h: %.class
。 -I
应该在 CPPFLAGS
而不是 CFLAGS
中,因为它用于预处理器。 -shared
然后应该进入 LDFLAGS
等等...
这是你的新 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)