16

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/

  • Please run strace -f java -version and post the output. – Gilles Jul 14 '11 at 17:19
  • This is strace result: dumpz.org/67368 – aetaur Jul 14 '11 at 17:47
12
open("$ORIGIN/../lib/i386/jli/tls/i686/sse2/cmov/libz.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)

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 to libc6-2.7-18lenny6, your java 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, and setcap -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 your PATH (sudo changes the PATH). Check what type java says — it's probably some different Java version for which ldd /path/to/bin/java reports libjli.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 the java 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 put libjli.so in the exact specified location, or set LD_LIBRARY_PATH to include where libjli.so is.

  • i'm updated originally post - ldd /path/to/bin/java is actually type java – aetaur Jul 14 '11 at 16:25
  • I'm tried to set root PATH and export LD_LIBRARY_PATH=/usr/lib/jvm/java-6-openjdk/jre/lib/i386/jli/, but got the same error. – aetaur Jul 14 '11 at 16:35
  • Ok, I lost my bet. It seems that your java executable has additional privileges, which is odd. – Gilles Jul 14 '11 at 19:31
4

I downloaded "1.7.0_60" from java.com in .tar.gz format and installed it into /usr/local/jre1.7.0_60. I then created a hard link to /usr/local/bin/java and received the error described above.

Changing the hardlink to a symbolic link fixed the issue.

Short version:

$ sudo ln /usr/local/jre1.7.0_60/bin/java /usr/local/bin/java

Is bad.

$ sudo ln -s /usr/local/jre1.7.0_60/bin/java /usr/local/bin/java

Is good.

2

Try to find the java executable inside the same path as libjli.so and use that.

E.g. I found libjli.so in /usr/lib/jvm/java-7-oracle/jre/lib/amd64/jli/libjli.so, so I used

find /usr/lib/jvm/java-7-oracle/ -name "java"

and found the executable in /usr/lib/jvm/java-7-oracle/bin/java. Then, I deleted java from /usr/bin and just symlinked above executable into /usr/bin.

2

If bug is due to using setcap on Java executable, then refer to

How to get Oracle java 7 to work with setcap cap_net_bind_service+ep and http://bugs.java.com/view_bug.do?bug_id=7157699

which answers this question in details.

ps. In our project we had to do

sudo setcap cap_net_bind_service=+ep /path/to/java

to allow java binary to open tcp/udp ports below 1024. Above java "bug" 7157699 provides quick solution, by adding directory where libjli.so is located into a conf file in /etc/ld.so.conf.d path and then calling ldconfig to re-cache libraries. Assuming Linux.

0

Check the permissions on that file. They should look like 0644/-rw-r--r--. If not, reinstall openjdk-6-jre-headless, because it would mean someone messed with the permissions.

  • 1
    ldd would report libjli.so => not found if it couldn't read the .so (at least that's what happens with GLibc 2.11). – Gilles Jul 14 '11 at 10:10
0

Similar to Tshepang's answer, I forced libjli.so into the library search path:

# find /usr/lib/jvm -name \libjli.so
/usr/lib/jvm/java-6-sun-1.6.0.45/jre/lib/amd64/jli/libjli.so

# export LD_LIBRARY_PATH=/usr/lib/jvm/java-6-sun/jre/lib/amd64/jli:$LD_LIBRARY_PATH


For reference, my build environment uses github:flexiondotorg/oab-java6 on Ubuntu 10.04/64-bit.

0

For some odd reason /usr/bin/java was no longer pointing to the java installation. No idea how this happened. I confirmed this by running:

$ sudo update-alternatives --config java

Which gave me the following

There is only one alternative in link group java (providing /usr/bin/java): /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java
Nothing to configure.
update-alternatives: warning: forcing reinstallation of alternative /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java because link group java is broken
update-alternatives: warning: not replacing /usr/bin/java with a link

So the solution was to remove the java in /usr/local/bin and create a new symlink:

$ sudo rm -rf /usr/bin/java
$ sudo ln -s /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java /usr/bin/java
0

I had the same error.

The simplest way to solve it is to simply remove all jdks and jres and also the executable /usr/bin/java, if it's there.

And then reinstall jdk.

It solved the problem for me. While other methods didn't.

0

For anyone trying to start a Java application from a systemd service and getting the same error, related to the libjli.so library, read on.

There is an open bug for this for Fedora currently:

Bug 1358476 – SELinux preventing systemd from exec’ing java-based services

Upshot of that is that SELinux is silently restricting access to that library. Because there is no AVC denied message, you can't fix it with context, or policy change.

I've found that adding a file /etc/ld.so.conf.d/ that contains the folder of your libjli.so file is one workaround:

/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-5.b14.fc26.x86_64/jre/lib/amd64/jli/

And then run

ldconfig

But that's pretty messy...

A better option is to use /bin/bash -c to launch the Java process in your service file:

ExecStart=/bin/bash -c "/usr/bin/java -Xmx1024m -jar myApp.jar NONINTERACTIVE"

Until the issue is fixed....

  • Does it have to be /bin/bash? What happens if you use /bin/sh? – G-Man Mar 15 '18 at 2:31
  • @G-Man Did you try it with /bin/sh ? I would guess that would also work but you'd have to try. Please update with how you go with it. Thanks – comfytoday Mar 16 '18 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.