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

aet*_*aur 17 permissions debian java dynamic-linking

我正在尝试启动 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
Run Code Online (Sandbox Code Playgroud)

但是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)
Run Code Online (Sandbox Code Playgroud)

更新:

/usr/lib/jvm/java-6-openjdk/jre/bin/java 实际上是我的java命令:

$ type java
java is hashed (/usr/bin/java)
$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 Jul 14 10:15 /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 40 Jul 14 10:36 /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Run Code Online (Sandbox Code Playgroud)

UPD2:

我也尝试设置根路径:

$ sudo su
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# exit
$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ java -version
java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

UPD3:

我试过:

# comm -3 <(declare | sort) <(declare -f | sort)
Run Code Online (Sandbox Code Playgroud)

根下。但是java没有可用的环境变量。

UPD4:

strace -f java -version结果:http : //dumpz.org/67368/

Gil*_*il' 12

open("$ORIGIN/../lib/i386/jli/tls/i686/sse2/cmov/libz.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
Run Code Online (Sandbox Code Playgroud)

除了正常的库搜索路径之外,您正在运行的可执行文件还会在rpath中查找库。这里的 rpath 是$ORIGIN/../lib/i386/jli:$ORIGIN/../jre/lib/i386/jli. 通常$ORIGIN应该替换为可执行文件的位置,这里/usr/lib/jvm/java-6-openjdk/jre/bin.

在这里,$ORIGIN不会被取代。该功能在以额外权限(setuid、setgid 或 setpcap)运行的可执行文件中关闭,否则您可能能够注入不同的库,从而以提升的权限运行任意代码。(更详细的解释见这篇文章。)安全问题是最近发现的;在 Debian 中,它已在DSA-2122-1 中修复,因此在您升级到 之前libc6-2.7-18lenny6,您的java可执行文件可能已经运行。

该症状表明java正在以附加权限运行。在正常的 Debian 安装中不是这种情况。确保它/usr/lib/jvm/java-6-openjdk/jre/bin/java是模式 755 并且没有任何功能(getcap /usr/lib/jvm/java-6-openjdk/jre/bin/java, 并setcap -r …删除功能(如果有)。


(原始答案,如果您发现它java以 root 身份运行而不以其他用户身份运行,这可能会很有用,而且事实证明您正在调用不同的二进制文件。)

我敢打赌,您javaPATH(sudo更改了PATH)上还有一些其他版本。检查type java说什么- 它可能是ldd /path/to/bin/java报告的某些不同的 Java 版本libjli.so => not found

我推测这个 Java 版本找不到的原因libjli.so是它正在通过与它的安装方式不匹配的 rpath(存储在可执行文件中的库搜索路径)来查找它。如果你有java二进制文件/some/where/bin/java,并且它有一个相对的 rpath(这是 Sun JDK 和 OpenJDK 的方式),那么库应该在/some/where/lib/i386/jli/libjli.so(假设是 i386 架构)。如果 rpath 是绝对路径,则需要放置libjli.so在确切的指定位置,或设置LD_LIBRARY_PATH为包含 where libjli.sois。


tsh*_*ang 0

检查该文件的权限。它们应该看起来像0644/-rw-r--r--。如果没有,请重新安装openjdk-6-jre-headless,因为这意味着有人弄乱了权限。