【问题标题】:Why java.library.path is not working on ubuntu?为什么 java.library.path 在 ubuntu 上不起作用?
【发布时间】:2014-12-23 06:46:30
【问题描述】:

我正在开发一个需要一些库的 java 组件,即 Windows 系统的 .dll 和 Linux 系统的 .so 文件。所以我在netbeans中准备了一个java应用程序并添加了一些依赖jar并构建了项目。

在 Windows 上执行:

当我尝试在 Windows 系统上使用命令 java -jar appName.jar 运行 jar 文件时,我得到了 java.lang.UnsatisfiedLinkError,所以我在像 java -Djava.library.path=full\\path\\to\\libs -jar appName.jar 这样执行时指定了 java.library.path,它在 Windows 上成功运行。

在 Linux(ubuntu) 上执行:

当我尝试在 ubuntu 上使用相同的命令 java -Djava.library.path=/path/to/libs -jar appName.jar 执行相同的 jar 文件时,我收到错误消息说在指定位置找不到某些 .so 文件(我检查了文件位置和权限,一切正常)

已更新(添加错误):

ubuntu@ubuntu-HP-dx2480-MT-KL969AV:~/Desktop$ java -Djava.library.path=/home/ubuntu/Desktop/bin -jar JavaApplication4.jar

使用库路径 bin 在 Thread[AWT-EventQueue-0,6,main] 上初始化 bin/jcef_helper:加载共享库时出错:libcef.so: 无法打开共享对象文件:没有这样的文件或目录

包含 bin 文件夹

-rwxr-xr-x 1 ubuntu ubuntu   1483321 Jun 18  2014 cef.pak
-rwxr-xr-x 1 ubuntu ubuntu   3258231 Jun 18  2014 devtools_resources.pak
-rwxr-xr-x 1 ubuntu ubuntu    971264 Jun 11  2014 ffmpegsumo.dll
-rwxr-xr-x 1 ubuntu ubuntu   9994752 Jun 11  2014 icudt.dll
-rwxr-xr-x 1 ubuntu ubuntu    429568 Jun 18  2014 jcef.dll
-rwxr-xr-x 1 ubuntu ubuntu    481488 Jun 18  2014 jcef_helper
-rwxr-xr-x 1 ubuntu ubuntu    233984 Jun 18  2014 jcef_helper.exe
-rwxr-xr-x 1 ubuntu ubuntu  53280768 Jun 11  2014 libcef.dll
-rwxr-xr-x 1 ubuntu ubuntu 105317136 Jun 18  2014 libcef.so
-rwxr-xr-x 1 ubuntu ubuntu   1309288 Jun 18  2014 libffmpegsumo.so
-rwxr-xr-x 1 ubuntu ubuntu   1047296 Jun 18  2014 libjcef.so drwxrwxrwx 2 ubuntu ubuntu      4096 Dec 23 11:29 locales

通过一些搜索,我知道我已经尝试使用 LD_LIBRARY_PATH 环境变量,所以我创建了一个带有命令的 sh 文件:

export LD_LIBRARY_PATH=/path/to/libs

java -jar /path/to/appName.jar  

当我运行 sh 文件时,我的程序运行成功。

所以我的问题是为什么 java.library.path 不适用于 ubuntu (linux)?是不是java.library.path 只适用于 Windows?

【问题讨论】:

  • -Djava.library.path=path/to/libs 这是一个错字还是你在这里使用相对路径?
  • 抱歉打错了,我使用完整路径,如 Windows 的 C:\winlibs\ 和 \home\ubuntu\Desktop\Linuxlibs
  • 您应该在此处提供错误消息以获得更好的答案。
  • @secmask,添加了有问题的错误。请找到更新(添加错误):
  • 您指定/home/ubuntu/Desktop/bin,可能这里的库需要其他不在这里的库吗?记住java.library.path 可以容纳多个路径。

标签: java chromium-embedded


【解决方案1】:

所以我的问题是为什么 java.library.path 不适用于 ubuntu (linux)?是不是 java.library.path 只适用于 windows?

它确实有效,我们经常使用它。使用-XshowSettings:properties 启动您的应用程序并查看搜索路径以进行调试。

我们通常将这些库作为一个包部署到/usr/local/lib,因为这些库也经常被其他组件使用。不要忘记在其中放置一个新库后致电ldconfig(export LD_LIBRARY_PATH 部分就这么多)。

据我记得应该如果我没记错的话,只需添加带有-Djava.library.path 的文件夹就足够了。我会调查一下,稍后再告诉你澄清。

另外请发帖readlink -f /home/ubuntu/Desktop/bin、file /home/ubuntu/Desktop/bin/libcef.so 和ldd /home/ubuntu/Desktop/bin/libcef.so。

更新: 我将尝试解释为什么事情有效,为什么不有效。

让我们谈谈java.library.path。 VM 使用此属性来查找库。看看java.lang.System#load*(String libName) 以供参考。 java.library.path 属性预先设置了一些路径,下面显示了我的 ubuntu 机器上的输出:

ortang@vbox-devel:~$ java -XshowSettings:properties
Property settings:
    ...
    java.library.path = /usr/java/packages/lib/amd64
        /usr/lib/x86_64-linux-gnu/jni
        /lib/x86_64-linux-gnu
        /usr/lib/x86_64-linux-gnu
        /usr/lib/jni
        /lib
        /usr/lib

请注意,使用此属性将覆盖现有属性。

ortwin@vbox-devel:~$ java -Djava.library.path=/some/other/folder:/yet/another/one -XshowSettings:properties
Property settings:
    ...
    java.library.path = /some/other/folder
        /yet/another/one

到目前为止一切顺利。 JVM 只查看该属性中定义的文件夹!

您让 JVM 加载的库很可能依赖于其他库。请注意,操作系统会查找这些依赖项,就像任何其他共享库一样!

因此,要解决您的问题,您必须确保您加载的库已解决其依赖关系!使用ldd 进行调试。

LD_LIBRARY_PATH 环境变量执行类似的工作,因为它添加了将用于操作系统查找库的路径。我不喜欢在生产环境中使用它。

【讨论】:

  • 是的,通过将所有文件从/home/ubuntu/Desktop/bin 复制到/usr/local/lib 为命令java -Djava.library.path=/home/ubuntu/Desktop/bin -jar appName.jar 工作。这也是不使用export LD_LIBRARY_PATH
  • readlink -f /home/ubuntu/Desktop/bin 给/home/ubuntu/Desktop/bin
  • file /home/ubuntu/Desktop/bin/libcef.so 给/home/ubuntu/Desktop/bin/libcef.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x2cba7c71da1e6000d154c84e3de947aa9380a2fd, not stripped
  • 我用 jcef_helper 尝试了file,因为根据我在问题 libcef.so 中发布的错误,在加载 jcef_helper file /home/ubuntu/Desktop/bin/jcef_helper 时找不到文件,所以给出了/home/ubuntu/Desktop/bin/jcef_helper: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x3cc71c45cf3d5d9e27f89cab9c5ea6b04165343a, not stripped
  • 对于jcef_helper,它显示(uses shared libs),所以我尝试ldd /home/ubuntu/Desktop/bin/jcef_helper在输出中显示libcef.so => not found,但在将文件添加到/usr/local/lib 后,文件路径已解析。
【解决方案2】:

我对您的问题的最佳猜测是您必须同时使用 java.library.path 和 LD_LIBRARY_PATH。实际上,j.l.p 是让 java 加载 JNI 库,而 L_L_P 是让操作系统加载共享库和任何依赖库。如果您的共享库依赖于其他路径中的其他库,则必须列出这些路径。

【讨论】:

  • 哦,就像为 Windows 设置 j.l.p 一样注意加载带有依赖库的库,而在 linux 设置中,j.l.p 正在加载依赖库,在我的情况下它的 jcef_helper 但 jcef_helper 需要 libcef.so 文件没有加载,所以我们需要设置 L_L_P 设置环境变量和 os 将负责加载库和依赖库,如果我在某处错了,请纠正我。
  • Windows 依赖不同的参数来加载 DLL,其中之一是与加载库相同的路径。另一种是PATH环境变量中列出的路径。
  • 好吧,我刚kalblogs.blogspot.in/2009/01/java.html这篇文章,现在明白为什么j.l.p 对linux sys 不够用了。就像jcef_helper 需要libcef.so 但是当我们设置 j.l.p 来解析库 (jcef_helper) 但是这个库引用或动态链接另一个文件 (libcef.so) 不是通过设置 j.l.p 加载的虽然两个文件都在同一个目录中IE /home/ubuntu/Desktop/bin,其中 L_L_P 加载所有库及其引用或动态链接的文件。
  • 您的理解似乎是正确的。因此,请同时指定 L_L_P 和 j.l.p,它应该可以工作。
【解决方案3】:

jcef 似乎没有找到它的依赖项,尝试ldd libcef.so |grep "not found" 和ldd libjcef.so |grep "not found" 并修复缺少的库。在我的机器上(ubuntu 14.04)它错过了libudev.so.0,我的机器有/lib/x86_64-linux-gnu/libudev.so.1所以用ln -s /lib/x86_64-linux-gnu/libudev.so.1 /lib/x86_64-linux-gnu/libudev.so.0和sudo ldconfig欺骗它来重新加载ld缓存。

【讨论】:

  • 对于libudev 我已经修复了。试试ldd jcef_helper,它会说libcef.so not found。至少在我的情况下
  • 通过将所有文件从/home/ubuntu/Desktop/bin 复制到/usr/local/lib 为命令java -Djava.library.path=/home/ubuntu/Desktop/bin -jar appName.jar 工作。也没有使用 export LD_LIBRARY_PATH
  • 请阅读@OrtwinAngermeier 给出的答案以及我在相同答案的 cmets 中的发现。
  • java load libjcef.so from it's code,从错误信息来看,可以说java可以看到并加载libjcef.so但是当libjcef.so加载libcef.so作为它的依赖时,错误是发生。说在搜索路径中找不到libcef.so。您可以尝试另一种方法是使用内容/home/ubuntu/Desktop/bin 创建文件/etc/ld.so.conf.d/cef.conf,然后使用sudo ldconfig 重新加载ld 缓存,同时测试LD_LIBRARY_PATH 在您的机器上是否正常工作。
  • 这是他们使 linux 工作的方式,linux 默认情况下不会在与可执行文件相同的路径中寻找共享库。但是您可以使用rpath 在搜索路径中包含可执行路径,请参阅readelf -d libjcef.so |grep runpath
【解决方案4】:

我遇到同样的问题,我使用“-Djava.library.path”,但它不起作用。 我添加“-Dsun.boot.library.path”作为尝试,它有效!

尝试:

java -Dsun.boot.library.path=/path/to/libs -jar appName.jar

【讨论】:

  • 如果它有效并且可能与问题无关 - sun.boot.library.path 与 java.library.path 的用途不同,因为前者用于与 JVM 本身相关的库后者用于与您要运行的项目相关的库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2019-05-07
  • 1970-01-01
  • 2015-10-19
相关资源
最近更新 更多