在 Debian 上启动 Java 时出现问题:“加载共享库时出错:libjli.so”

在 Debian 上启动 Java 时出现问题:“加载共享库时出错:libjli.so”

我正在尝试启动 Java:

$ java -version
java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

$ ldd /usr/lib/jvm/java-6-openjdk/jre/bin/java
        linux-gate.so.1 =>  (0xb779f000)
        libz.so.1 => /usr/lib/libz.so.1 (0xb7780000)
        libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7767000)
        libjli.so => /usr/lib/jvm/java-6-openjdk/jre/bin/../lib/i386/jli/libjli.so (0xb7762000)
        libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb775e000)
        libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7603000)
        /lib/ld-linux.so.2 (0xb77a0000
$ ls /usr/lib/jvm/java-6-openjdk/jre/bin/../lib/i386/jli/
libjli.so

然而 Java 在 root 下可以工作:

$ sudo java -version
java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.7) (6b18-1.8.7-2~lenny1)
OpenJDK Client VM (build 14.0-b16, mixed mode, sharing)

我如何才能以普通用户身份启动 Java 并且不会出现错误?

答案1

注意链接的配置方式。我发现一个服务器发生了错误,/etc/bin/java 被二进制文件替换。这导致出现未找到库的错误。我将 /usr/bin/java 重新链接到 /etc/alternatives/java,一切又恢复正常。

# namei -mx /usr/bin/java
f: /usr/bin/java
 drwxr-xr-x /
 drwxr-xr-x usr
 drwxr-xr-x bin
 lrwxrwxrwx java -> /etc/alternatives/java
   drwxr-xr-x /
   drwxr-xr-x etc
   drwxr-xr-x alternatives
   lrwxrwxrwx java -> /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java
     drwxr-xr-x /
     drwxr-xr-x usr
     drwxr-xr-x lib
     drwxr-xr-x jvm
     lrwxrwxrwx jre-1.6.0-openjdk.x86_64 -> java-1.6.0-openjdk-1.6.0.0.x86_64/jre
       drwxr-xr-x java-1.6.0-openjdk-1.6.0.0.x86_64
       drwxr-xr-x jre
     drwxr-xr-x bin
     -rwxr-xr-x java

我的直觉是,OpenJDK 在寻找库时会进行某种路径规范化。

答案2

也许你有一个没有提升权限的 Ubuntu 实例,但它仍然找不到库正如本报告中所述

尝试

ln -s /usr/lib/jvm /lib

答案3

当你在 chroot-jail 中运行 java 时,出现了这个问题。

如果你从 chroot 中使用 chrpath 检查,你会看到类似这样的内容:

chrpath /opt/test/demo/opt/test/jdk/bin/java
/opt/test/demo/opt/test/jdk/bin/java: RPATH=$ORIGIN/../lib/amd64/jli:$ORIGIN/../jre/lib/amd64/jli

为了安全起见,ELF 不会评估 $ORIGIN,因为它不是环境变量,所以您必须在运行 java 之前设置一些环境变量:

export JAVA_HOME=/opt/test/jdk
export LD_LIBRARY_PATH=$JAVA_HOME/lib/amd64/jli:$JAVA_HOME/jre/lib/amd64/jli

或者

LD_ORIGIN_PATH=/opt/test/jdk/bin /opt/test/jdk/bin/java

答案4

我知道这是一个非常老的问题,但我刚刚遇到了同样的问题并认为以下链接可能会有所帮助:

https://unix.stackexchange.com/questions/87978/how-to-get-oracle-java-7-to-work-with-setcap-cap-net-bind-serviceep

如果您向 java 可执行文件授予 posix 功能,则可能会出现此问题。在这种情况下,如果以非 root 用户身份运行 java,ld.so 将拒绝链接 libjli.so。详细原因和解决方案可以在上面的链接中找到,但简而言之,以 root 身份执行以下命令应该可以解决问题:

echo /opt/java/jdk1.7.0_71/lib/amd64/jli >> /etc/ld.so.conf.d/java.conf
rm /etc/ld.so.cache
ldconfig -v|grep jli

记得用你实际的 java 主路径替换/opt/java/jdk1.7.0_71,如果你在 32 位机器上,请使用 /lib/i386/jli。如果最后一条命令返回类似

libjli.so -> libjli.so

,你应该一切顺利。如果 ld.so 缓存未正确刷新,在某些情况下,你可能需要重新启动计算机。

相关内容