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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7284129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 06:00:28  来源:igfitidea点击:

JNI issue on Linux: cannot open shared object file

linuxjava-native-interface

提问by Vlemmix

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

我在这里看到了这个问题,尝试了建议的修复,但到目前为止对我来说没有成功。我有相当多的 Java 经验,但 JNI 是很久以前的事了,虽然从未在 Linux 上做过...

I'm trying to get a simple HelloWorld JNI app running on Linux.

我正在尝试在 Linux 上运行一个简单的 HelloWorld JNI 应用程序。

Small java file:

小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");
    }

}

Small C file:

小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;
}

compiled the C file by:

通过以下方式编译 C 文件:

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

奇怪,因为实际上有一个/home/nxp40954/jnitesting/libHelloWorld.so文件。

Does anyone have a clue?

有人有线索吗?

回答by Micha? ?rajer

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.

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

I'm on 32bit ubuntu with sun java. I was compiling this way:

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

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

回答by Simon C

Your example worked for me on a 32-bit Linux installation.

您的示例在 32 位 Linux 安装上对我有用。

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 -d64when starting Java so that Java can load the 64-bit shared library.

您的共享库是编译为 32 位还是 64 位共享库?用命令检查file libHelloWorld.so。如果您的共享库是 64 位,那么您需要-d64在启动 Java 时提供命令行选项,以便 Java 可以加载 64 位共享库。

If your shared library is 32-bit then perhaps the Java option -d32will solve the problem.

如果您的共享库是 32 位的,那么 Java 选项-d32可能会解决问题。

回答by Heri

Clarification on java.library.pathand system path:

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

java.library.path is a JVM-Variable which can be set - e.g. - by the command line parameter

java.library.path 是一个 JVM 变量,可以设置 - 例如 - 通过命令行参数

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

由 java 调用加载的 DLL(在 Windows 上)等(在 linux 上)loadLibrary()必须位于 java.library.path 中。如果它是通过 JNI 加载的,它必须位于系统路径中。

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 PATHenvironment variable, in linux it's the LD_LIBRARY_PATHenvironment variable (for linked libraries).

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

Another point to ensure in linux: Verify that the linked library has executable permissions for the current user. Usually a

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

sudo chmod 755 myLinkedLib

does the trick.

诀窍。