在ubuntu上使用JNI时出现java.lang.UnsatisfiedLinkError [英] java.lang.UnsatisfiedLinkError when using JNI on ubuntu

查看:242
本文介绍了在ubuntu上使用JNI时出现java.lang.UnsatisfiedLinkError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

java.lang.UnsatisfiedLinkError.

java.lang.UnsatisfiedLinkError when using JNI.

我的测试环境:

Ubuntu 12.04/64位
JDK 1.7
gcc(Ubuntu/Linaro 4.6.3-1ubuntu5)

Ubuntu 12.04/64-bit
JDK 1.7
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5)

这是我的java来源:

This is my java source:

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:

This is my 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应用时,会出现OLD问题:

拾取了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
线程主"中的异常java.lang.UnsatisfiedLinkError:java.library.path中没有libHelloJNI
at 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

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

我已经在互联网上搜索了此问题,发现这是一个 OLD问题.但是我无法找到解决我问题的任何方法!希望可以有人帮帮我. 提前谢谢.

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.

推荐答案

您需要在Makefile中添加-Djava.library.path=.,并且需要使用 System.loadLibrary("HelloJNI");-没有lib前缀,没有后缀.前缀和后缀由Java处理-考虑一下,Windows上的命名方案不同(愚蠢但事实).并且要注意在代码中两次使用System.loadLibrary()的陷阱,如果仅更改其中之一,它仍然会失败.那实际上花了我几分钟:P

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 .:我建议对您的Makefile进行一些更改.我会使用$(RM)而不是rm.不是文件的目标应声明为.PHONY.可以使用:=而不是=分配不引用自动变量的变量.我将使用一个单独的步骤从.o文件创建.so.我会使用模式规则来编译Java,例如%.class: %.java.我将使用模式规则来创建头文件,例如%.h: %.class. -I的内容应该在CPPFLAGS中,而不是在CFLAGS中,因为它是用于预处理程序的.然后-shared应该进入LDFLAGS,依此类推...

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

这是您的新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)

这篇关于在ubuntu上使用JNI时出现java.lang.UnsatisfiedLinkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆