使用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.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
上java.library.path中没有libHelloJNI HelloJNI.main(HelloJNI.java:22)
的java.lang.System.loadLibrary(System.java:1088)
的.lang.Runtime.loadLibrary0(Runtime.java:849)
make:*** [run] Error 1
我已经在互联网上搜索了这个问题,发现这是一个古老的问题。但我CAN NOT找到任何方法来解决我的问题!希望可以有人帮帮我。预先谢谢。
您需要-Djava.library.path=.
在Makefile中,并且需要使用System.loadLibrary("HelloJNI");
-无lib
前缀,无.so
后缀加载库。前缀和后缀由Java处理-考虑一下,Windows上的命名方案不同(愚蠢但事实)。并且要注意System.loadLibrary()
代码中有两次陷阱,如果仅更改其中之一,它仍然会失败。那实际上花了我几分钟:P
PS:我建议对您的Makefile进行一些更改。我会用$(RM)
代替rm
。应该声明不是文件的目标.PHONY
。可以使用:=
代替分配不引用自动变量的变量=
。我将使用一个单独的步骤来.so
从.o
文件创建。我会使用模式规则来编译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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句