我正在尝试加载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");
}
任何人都可以建议
答案 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。