使用 JNI 时出现 java.lang.UnsatisfiedLinkError。
我的测试环境:
Ubuntu 12.04/64 位
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 应用程序时,出现了老问题:
选择了 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 目录
线程“main”中出现异常 java.lang.UnsatisfiedLinkError:java.library.path 中没有 libHelloJNI
在 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
在 java.lang.Runtime.loadLibrary0(Runtime.java:849)
在 java.lang.System.loadLibrary(System.java:1088)
在 HelloJNI.main(HelloJNI.java:22)
make: *** [运行] 错误 1
我在网上搜索了这个问题,发现这是一个老问题. But I CANNOT找到任何方法来解决我的问题!希望可以有人帮帮我。提前致谢.
你需要-Djava.library.path=.
在 Makefile 中,您需要使用以下命令加载库System.loadLibrary("HelloJNI");
- no lib
前缀,无.so
suffix。前缀和后缀由 Java 处理 - 想想看,Windows 上的命名方案是不同的(愚蠢但事实)。并小心你所面临的陷阱System.loadLibrary()
代码中两次,如果只更改其中之一,仍然会失败。那实际上花了我几分钟:P
P.S.:我建议对你的 Makefile 进行一些更改。我会用$(RM)
代替rm
。应该声明不是文件的目标.PHONY
。不引用自动变量的变量可以用:=
代替=
。我会使用一个单独的步骤来创建.so
来自.o
文件。我会使用模式规则来编译 Java,例如%.class: %.java
。我会使用模式规则来创建头文件,例如%.h: %.class
. The -I
东西应该在CPPFLAGS
not 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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)