I'm trying to launch 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
But java works under 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)
UPD:
/usr/lib/jvm/java-6-openjdk/jre/bin/java is actually my java command:
$ 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
UPD2:
I've also tried to set root PATH:
$ 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
UPD3:
I'm tried:
# comm -3 <(declare | sort) <(declare -f | sort)
under root. But there is no usable environment variables for java.
UPD4:
strace -f java -version
result: http://dumpz.org/67368/
Best Answer
The executable you're running looks for libraries in an rpath in addition to the normal library search path. The rpath here is
$ORIGIN/../lib/i386/jli:$ORIGIN/../jre/lib/i386/jli
. Normally$ORIGIN
should be replaced by the location of the executable, here/usr/lib/jvm/java-6-openjdk/jre/bin
.Here,
$ORIGIN
isn't being replaced. The feature is turned off in executables running with extra privileges (setuid, setgid, or setpcap), because otherwise you might be able to inject a different library and so run arbitrary code with elevated privileges. (See this article for a more detailed explanation.) The security issue was discovered relatively recently; in Debian it was fixed in DSA-2122-1, so before you upgraded tolibc6-2.7-18lenny6
, yourjava
executable would presumably have worked.The symptom indicates that
java
is running with additional privileges. This is not the case in a normal Debian installation. Make sure that/usr/lib/jvm/java-6-openjdk/jre/bin/java
is mode 755 and doesn't have any capabilities (getcap /usr/lib/jvm/java-6-openjdk/jre/bin/java
, andsetcap -r …
to remove the capabilities if any).(Original answer, which may be useful if you find that
java
works as root but not as other users, and it does turn out that you're invoking different binaries.)My bet is that you have some other
java
version earlier on yourPATH
(sudo
changes thePATH
). Check whattype java
says — it's probably some different Java version for whichldd /path/to/bin/java
reportslibjli.so => not found
.And I speculate that the reason that this Java version can't find
libjli.so
is that it's looking for it through a rpath (library search path stored in the executable) that doesn't match the way it's installed. If you have thejava
binary in/some/where/bin/java
, and it has a relative rpath (which is the way of the Sun JDK and OpenJDK), the library should be in/some/where/lib/i386/jli/libjli.so
(assuming an i386 architecture). If the rpath is absolute, you need to either putlibjli.so
in the exact specified location, or setLD_LIBRARY_PATH
to include wherelibjli.so
is.