加载JNI Ubuntu失败

时间:2015-09-15 10:51:11

标签: java c gcc java-native-interface

我正在尝试加载JNI库并运行以下程序,但我收到以下错误

Exception in thread "main" java.lang.UnsatisfiedLinkError: no JNIDemo      
in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at demo.JNIWrapper.<clinit>(JNIWrapper.java:10)

以下是我的Java,C,命令

Step1:Java代码:存在于Path项目的Eclipse项目中(/ documents / JNIDemoProject / src / main / java / demo)

package demo;

public class JNIWrapper {

static{


    //System.load("/home/arpit/Documents/JNI/libJNIDemo.so");

    System.loadLibrary("JNIDemo");
}


public native int multiply(int a,int b);


public static void main(String args[]){

    try{

    JNIWrapper jni=new JNIWrapper();
    int result=jni.multiply(7, 8);
    System.out.println("Result is "+result);
    }catch(Exception e){
        e.printStackTrace();
    }

}

}

步骤2:创建名为demo_JNIWrapper的.h文件(注意名称是demo_JNIWrapper,因为我必须从/ documents / JNIDemoProject / src / main / java运行javah命令)

 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class demo_JNIWrapper */

#ifndef _Included_demo_JNIWrapper
#define _Included_demo_JNIWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     demo_JNIWrapper
 * Method:    multiply
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_demo_JNIWrapper_multiply
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif


#endif

第3步: 我创建了一个C文件

#include<stdio.h>
#include <jni.h>
#include "demo_JNIWrapper.h"

JNIEXPORT jint JNICALL Java_demo_JNIWrapper_multiply
 (JNIEnv *env, jobject jobj, jint a, jint b){

int result=a*b;
return result;
}

第4步: 我创建了名为libJNIDemo.so的lib文件

第5步: 所有三个文件(libJNIDemo.so,demo_JNIWrapper.h,HelloJNI.c)都位于文件夹/ users / documents / JNI

第6步: 我将它导出到lib路径 export LD_LIBRARY_PATH="/users/documents/JNI"

步骤7: 当我运行java程序时,它给了我上面的错误。

注意事项: 当我使用路径

直接加载libJniDemo.so文件时,我的程序运行正常
static{


    System.load("/users/documents/JNI/libJNIDemo.so");

    //System.loadLibrary("JNIDemo");
}

任何人都可以建议

1 个答案:

答案 0 :(得分:0)

Java在Linux(以及其他Unix或类Unix操作系统)上使用dlopen()来查找本机库。来自Linux dlopen() man page

   If filename is NULL, then the returned handle is for the main
   program.  If filename contains a slash ("/"), then it is interpreted
   as a (relative or absolute) pathname.  Otherwise, the dynamic linker
   searches for the object as follows (see ld.so(8) for further
   details):

   o   (ELF only) If the executable file for the calling program
       contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
       then the directories listed in the DT_RPATH tag are searched.

   o   If, at the time that the program was started, the environment
       variable LD_LIBRARY_PATH was defined to contain a colon-separated
       list of directories, then these are searched.  (As a security
       measure, this variable is ignored for set-user-ID and set-group-
       ID programs.)

   o   (ELF only) If the executable file for the calling program
       contains a DT_RUNPATH tag, then the directories listed in that
       tag are searched.

   o   The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
       checked to see whether it contains an entry for filename.

   o   The directories /lib and /usr/lib are searched (in that order).

如果可以,可以在strace下运行您的Java进程,跟踪open次调用,并查看JVM在哪里寻找您的本机库,以及它正在寻找的内容。< / p>

了解dlopen()的工作方式以及来自strace的信息,您应该能够准确确定发生了什么。

有一点需要注意:您可能正在创建一个64位本机库,但运行的是32位JVM。