java.lang.UnsatisfiedLinkError:[库路径] / [JNI绑定库].so:[实际代码库].so:无法打开共享对象文件:没有那个文件或目录
这让我相信JNI包装库已成功加载,但当该库尝试加载包含实际代码的库时会失败。是否有任何方法可以进一步调试此问题?
我还要指出,这个问题发生在Eclipse编辑器本身中,而我还没有尝试将代码打包成一个jar并在单独的JVM实例中运行它。
java.lang.UnsatisfiedLinkError:[库路径] / [JNI绑定库].so:[实际代码库].so:无法打开共享对象文件:没有那个文件或目录
这让我相信JNI包装库已成功加载,但当该库尝试加载包含实际代码的库时会失败。是否有任何方法可以进一步调试此问题?
我还要指出,这个问题发生在Eclipse编辑器本身中,而我还没有尝试将代码打包成一个jar并在单独的JVM实例中运行它。
可能只是需要在运行配置对话框中找到正确的位置来放置 -Djava.library.path=... 选项。 我想你希望在参数选项卡上将 -D 定义放在“vm arguments”中,而如果您想定义 LD_LIBRARY_PATH,则将其放在环境选项卡上。无论如何,我以前就是这样使用库的,如果有机会我会查找我做了什么并在此编辑我的答案。
另一种尝试的方法是玩一下 LD_DEBUG。 您可以将环境变量 LD_DEBUG 设为各种值(尝试 ALL),然后 Linux 加载器将披露有关应用程序正在尝试加载的内容、位置等所有有用信息。当然,这预设您从命令行启动 Eclipse,因此您可以设置环境变量并查看加载器诊断;但是对于系统而言,在 Eclipse 内运行应用程序时,您的应用程序只是 Eclipse 执行的某些操作,因此可以通过这种方式查看任何库加载行为。
你的两个库是否依赖于其他库?如果是,你需要确保它们对JVM也是可访问的。
请注意,手动设置“-Djava.library.path”似乎会擦除默认的库路径。
因此,使用以下代码:
public class LibTest {
public static void main(String[] args) {
String property = System.getProperty("java.library.path");
StringTokenizer parser = new StringTokenizer(property, ":");
while (parser.hasMoreTokens()) {
System.err.println(parser.nextToken());
}
}
}
从Java 1.6.0_14在Eclipse中启动输出:
/opt/java/jre/lib/i386/client
/opt/java/jre/lib/i386
/opt/java/jre/../lib/i386
/opt/java/jre/lib/i386/client
/opt/java/jre/lib/i386
/usr/lib/xulrunner-devel-1.9.0.11
/usr/lib/xulrunner-devel-1.9.0.11
/usr/java/packages/lib/i386
/lib
/usr/lib
/tmp/
如果您手动设置了java.library.path,这可能解释了为什么ldd从命令行工作,但您的.so文件在eclipse/java中无法工作。
您可以尝试不设置java.library.path,并使用绝对路径调用System.load来加载库,而不是调用System.loadLibrary。这样可以让JVM找到您的.so文件,并在搜索其依赖项时仍使用默认路径。
当然,如果这没有用,您还可以尝试在命令行上使用“-verbose:jni”打开jni调试输出。这可能会给您一些解决问题的线索。
是的,LD_LIBRARY_PATH 对我有效
你可以尝试在命令行参数中加入-Djava.library.path=actual.so
。
在Windows上,我曾经遇到过类似的问题,当时使用了一个JNI包装DLL来调用第三方库的DLL。我的项目将DLL文件放在了lib目录下,所以我将lib添加到了PATH环境变量中(例如:PATH=%PATH%;./lib
),然后一切都开始正常工作了。
添加这个答案可能会有用。在AIX机器上,我们需要设置LIBPATH环境变量而不是LD_LIBRARY_PATH。