Linux 上的 JNI 问题:无法打开共享对象文件

发布于 2024-12-02 22:41:43 字数 1416 浏览 0 评论 0原文

我在这里看到了这个问题,尝试了建议的修复,但到目前为止对我来说没有成功。我有相当多的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沫离伤花 2024-12-09 22:41:43

这样执行:

export LD_LIBRARY_PATH=.
java HelloWorld

当.so文件无法加载时,抛出java.lang.UnsatisfiedLinkError。
LD_LIBRARY_PATH 变量指向查找 *.so 文件的额外位置。

我使用的是 32 位 ubuntu 和 sun java。我是这样编译的:

gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -o libHelloWorld.so

execute this way:

export LD_LIBRARY_PATH=.
java HelloWorld

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:

gcc -shared -Wall -fPIC HelloWorld.c -I/usr/lib/jvm/java-6-sun-1.6.0.26/include -I/usr/lib/jvm/java-6-sun-1.6.0.26/include/linux -o libHelloWorld.so
ぺ禁宫浮华殁 2024-12-09 22:41:43

你的例子在 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.

两仪 2024-12-09 22:41:43

关于 java.library.path 和系统路径的说明:

进行设置

-Djava.library.path=xy

java.library.path 是一个 JVM 变量,可以通过命令行参数DLL(在 Windows 上)等(在 Linux 上) )由 java 调用 loadLibrary() 加载的内容必须位于 java.library.path 中。如果它是通过 JNI 加载的,则它必须位于系统路径中。

如果这样的链接库加载另一个链接库,则必须在系统路径中找到后者。在 Windows 中,系统路径根据 PATH 环境变量进行解析,在 Linux 中,系统路径是 LD_LIBRARY_PATH 环境变量(用于链接库)。

linux中还要确保的一点:验证链接库对于当前用户是否具有可执行权限。通常 a

sudo chmod 755 myLinkedLib

就可以解决问题。

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

-Djava.library.path=xy

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 the LD_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

sudo chmod 755 myLinkedLib

does the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文