Linux 上的 JNI 问题:无法打开共享对象文件
我在这里看到了这个问题,尝试了建议的修复,但到目前为止对我来说没有成功。我有相当多的 Java 经验,但 JNI 是很久以前的事了,虽然从未在 Linux 上做过...
我正在尝试在 Linux 上运行一个简单的 HelloWorld JNI 应用程序。
小java文件:
class HelloWorld {
private native void print();
public static void main(String[] args){
new HelloWorld().print();
}
static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("HelloWorld");
}
}
小C文件:
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
编译C文件通过:
gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/gcc/x86_64-redhat-linux/3.4.3/include/ -o libHelloWorld.so
运行应用程序:
java HelloWorld
或
java -Djava.library.path=/home/nxp40954/jnitesting/. HelloWorld
但没有好处,得到一个:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/nxp40954/jnitesting/libHelloWorld.so: /home/nxp40954/jnitesting/libHelloWorld.so: cannot open shared object file: No such file or directory
奇怪,因为实际上有一个 /home/nxp40954/jnitesting/libHelloWorld.so
文件。
有人知道吗?
I've seen this question on here, tried the proposed fixes, but no success so far for me. I have quite some Java experience, but JNI is a long time ago, never did it on Linux though...
I'm trying to get a simple HelloWorld JNI app running on Linux.
Small java file:
class HelloWorld {
private native void print();
public static void main(String[] args){
new HelloWorld().print();
}
static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("HelloWorld");
}
}
Small C file:
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
compiled the C file by:
gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/gcc/x86_64-redhat-linux/3.4.3/include/ -o libHelloWorld.so
Run the app by:
java HelloWorld
or
java -Djava.library.path=/home/nxp40954/jnitesting/. HelloWorld
But no good, getting a:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/nxp40954/jnitesting/libHelloWorld.so: /home/nxp40954/jnitesting/libHelloWorld.so: cannot open shared object file: No such file or directory
Strange, because there is actually a /home/nxp40954/jnitesting/libHelloWorld.so
file.
Does anyone have a clue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这样执行:
当.so文件无法加载时,抛出java.lang.UnsatisfiedLinkError。
LD_LIBRARY_PATH 变量指向查找 *.so 文件的额外位置。
我使用的是 32 位 ubuntu 和 sun java。我是这样编译的:
execute this way:
The java.lang.UnsatisfiedLinkError is thrown when the .so file cannot be loaded.
The LD_LIBRARY_PATH variable points extra location to look for the *.so files.
I'm on 32bit ubuntu with sun java. I was compiling this way:
你的例子在 32 位 Linux 安装上对我有用。
您的共享库是编译为 32 位还是 64 位共享库?使用命令
file libHelloWorld.so
检查。如果您的共享库是64位的,那么您需要在启动Java时提供命令行选项-d64
,以便Java可以加载64位共享库。如果您的共享库是 32 位的,那么 Java 选项
-d32
或许可以解决问题。Your example worked for me on a 32-bit Linux installation.
Is your shared library compiled as a 32-bit or 64-bit shared library? Check with command
file libHelloWorld.so
. If your shared library is 64-bit then you need to give command line option-d64
when starting Java so that Java can load the 64-bit shared library.If your shared library is 32-bit then perhaps the Java option
-d32
will solve the problem.关于 java.library.path 和系统路径的说明:
进行设置
java.library.path 是一个 JVM 变量,可以通过命令行参数DLL(在 Windows 上)等(在 Linux 上) )由 java 调用
loadLibrary()
加载的内容必须位于 java.library.path 中。如果它是通过 JNI 加载的,则它必须位于系统路径中。如果这样的链接库加载另一个链接库,则必须在系统路径中找到后者。在 Windows 中,系统路径根据
PATH
环境变量进行解析,在 Linux 中,系统路径是LD_LIBRARY_PATH
环境变量(用于链接库)。linux中还要确保的一点:验证链接库对于当前用户是否具有可执行权限。通常 a
就可以解决问题。
Clarification on
java.library.path
and system path:java.library.path is a JVM-Variable which can be set - e.g. - by the command line parameter
DLL's (on windows) and so's (on linux) which are loaded by the java call
loadLibrary()
must be located in the java.library.path. If it is loaded via JNI it must be located in the system path.If such a linked library loads another linked library, latter must be found in the system path. In Windows the system path is resolved against the
PATH
environment variable, in linux it's theLD_LIBRARY_PATH
environment variable (for linked libraries).Another point to ensure in linux: Verify that the linked library has executable permissions for the current user. Usually a
does the trick.