2

I have a Java application installed on a USB which the user should be able to run from any OS.

For this,

  1. I'm packaging a JRE instance on the USB along with my application.
  2. I'm having a FAT32 file-system on the USB.

However, the problem is, FAT32 has no concept of execute ("+x") permissions. While I can launch a shell script, like so:

$ sh /path/to/fat32-usb/helloWorld.sh

, and while I can launch a simple ELF binary, like so:

$ /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/helloWorld

, I can't seem to be able to launch the Java ELF program. I get these errors:

Error: could not find libjava.so
Error: Could not find Java SE Runtime Environment.

Before launching java, I've tried setting these environment variables as follows:

export JAVA_HOME=/path/to/fat32-usb/jre
export LD_LIBRARY_PATH="$JAVA_HOME/lib/amd64:.:$LD_LIBRARY_PATH" 
export PATH="$JAVA_HOME/bin:.:$PATH"

I have also tried launching java from inside the $JAVA_HOME/bin directory. Finally, I've also tried copying all the libXXX.so's from $JAVA_HOME/lib/amd64/ to $JAVA_HOME/bin, hoping that they would get picked up from the current directory, ., somehow.

But nothing has worked.

EDIT

Here are the last few lines of strace output:

$ strace -vfo /tmp/java.strace /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/jre ...
...
readlink("/proc/self/exe", "/lib/x86_64-linux-gnu/ld-2.17.so", 4096) = 32
write(2, "Error: could not find libjava.so", 32) = 32
write(2, "\n", 1)                       = 1
write(2, "Error: Could not find Java SE Ru"..., 50) = 50
write(2, "\n", 1)                       = 1
exit_group(2)                           = ?

EDIT2

And here is the output of ltrace (just a single line!):

$ ltrace -s 120 -e '*' -ifo /tmp/java.ltrace /lib64/ld-linux-x86-64.so.2 /path/to/fat32-usb/jre ...
30913 [0xffffffffffffffff] +++ exited (status 2) +++

EDIT 3

This is ltrace excerpt around loading of libjava.so by a Java on an ext4 partition (and not the problem FAT32 partition), which I can load fine:

5525 [0x7f7627600763] <... snprintf resumed> "/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", 4096, "%s/lib/%s/libjava.so", "/home/aaa/bbb/jdk1.7.0_40", "amd64") = 46
5525 [0x7f762760076d] libjli.so->access("/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", 0)                                                                 = -1
5525 [0x7f762760078d] libjli.so->snprintf( <unfinished ...>
5525 [0x3085246bdb] libc.so.6->(0, 0x7fffffd8, 0x7f7627607363, 39)                                                                                           = 0
5525 [0x3085246be3] libc.so.6->(0, 0x7fffffd8, 0x7f7627607363, 39)                                                                                           = 0
5525 [0x7f762760078d] <... snprintf resumed> "/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", 4096, "%s/jre/lib/%s/libjava.so", "/home/aaa/bbb/jdk1.7.0_40", "amd64") = 50
5525 [0x7f7627600797] libjli.so->access("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", 0)                                                             = 0

And this is the strace output of, again, the healthy/loading java.

5952  readlink("/proc/self/exe", "/home/aaa/bbb/jdk1.7.0_40/bin/ja"..., 4096) = 34
5952  access("/home/aaa/bbb/jdk1.7.0_40/lib/amd64/libjava.so", F_OK) = -1 ENOENT (No such file or directory)
5952  access("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/libjava.so", F_OK) = 0
5952  open("/home/aaa/bbb/jdk1.7.0_40/jre/lib/amd64/jvm.cfg", O_RDONLY) = 3
nxs
  • 21
  • 4
  • What architecture is your current machine? And did you export your new `LD_LIBRARY_PATH` before you run `java`? – Lee Duhem Mar 01 '14 at 09:35
  • Arch is x86-64. Yes, all the environment variables were modified before running `java`. (`uname -a` returns: `Linux mybox 3.10.11-100.fc18.x86_64 #1 SMP Mon Sep 9 13:06:31 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux`) – nxs Mar 01 '14 at 10:05
  • Have you tried `ldd /path/to/java`? Did it give the same error? – Lee Duhem Mar 01 '14 at 10:21
  • I get a warning, not an error: `ldd: warning: you do not have execution permission for '/path/to/java'`. It then goes ahead and lists the various `lib*.so` dependencies anyway. – nxs Mar 01 '14 at 10:40
  • Well, that is odd. You said this `java` located in a USB device, right? Then maybe it uses a different loader? `readelf -l /path/to/java` will show which loader this `java` use, make sure your system has that file. – Lee Duhem Mar 01 '14 at 10:47
  • `readelf -l /path/to/java` says: `... [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] ...`, and I'm using the exact same loader (in its absolute path form) to load `/path/to/java`. – nxs Mar 01 '14 at 10:50
  • Then I guess you need to run your `java` by `/path/to/loader /path/to/java ...`, if this works for you. – Lee Duhem Mar 01 '14 at 10:58
  • Did `libjava.so` in the libraries list given by `ldd /path/to/java`? In my system, it DOES NOT. Maybe we are in the wrong way, maybe it is not that loader cannot find this `libjava.so`, maybe it is `java` itself some how cannot find this `libjava.so`. – Lee Duhem Mar 01 '14 at 11:02
  • No, `libjava.so` does not figure in the list given by `ldd /path/to/java`. I am already issuing `/path/to/loader /path/to/java`, both from within the `/path/to` directory and from outside it. – nxs Mar 01 '14 at 11:09
  • I guess it is indeed `java` itself who try to find `libjava.so`. Then try `strace -o /tmp/java.strace /path/to/java` and search `libjava` in `/tmp/java.strace`. You may find where `java` expects this `libjava.so` at. – Lee Duhem Mar 01 '14 at 11:18
  • I've added `strace` output to my original question. What else to try now?? – nxs Mar 01 '14 at 12:01
  • The output of `strace` supposes to have a line like `access("/patch/to/libjava.so", ...) = -1` after that `readlink("/proc/self/exe", ... `; and another `open("/path/to/libjava.so", ...)` if you given `strace` the `-f` option. To be honest, if `strace -vfo /tmp/java.strace /path/to/java` still cannot give you any clue of what is going wrong, I am out of options. – Lee Duhem Mar 01 '14 at 13:05
  • Try `ltrace -s 120 -e '*' -ifo /tmp/java.ltrace /path/to/java`. I have strong feelings that this will reveal who wants to open `libjava.so` and why it cannot find it. – Lee Duhem Mar 01 '14 at 13:22
  • In the `strace -vfo` invocation too, there's no line between `readlink("/proc/self/exe"...` and `write(2, "Error: could not find libjava.so`. When using `ltrace`, I only get a single line: `30913 [0xffffffffffffffff] +++ exited (status 2) +++`, and that's it! – nxs Mar 02 '14 at 02:12
  • Using `ltrace -s 120 -e '*' -ifo /tmp/java.ltrace /path/to/java`, DO NOT run your `java` by loader. – Lee Duhem Mar 02 '14 at 08:47
  • I see what you're saying. If I don't use the loader, I get the `Can't execute '/path/to/java': Permission denied` error, again because of fat32 limitations. So, I ran the `ltrace` on a healthy `java` on my `ext4` partition that has no problems loading. I've included the `libjava.so` excerpt from its output in **EDIT3** section above. Apparently, internally what is happening is, `java` tries to construct the path of `libjava.so` using `snprintf`, and this file very much exists on the FAT32 partition, just as it does on the `ext4` partition. So, not sure what's the problem now. – nxs Mar 03 '14 at 06:08
  • Oh, I forgot the FAT32 execute permission problem you have at the first place. If you can see through `strace` that `libjli.so` is loaded normally in your FAT32 case, then I am really out of options. – Lee Duhem Mar 03 '14 at 06:14
  • Thanks a lot, anyway, for your time. :-( – nxs Mar 03 '14 at 06:16
  • You are welcome. It is unfortunate that I am unable to help. If you solved this problem evently, please do not forget to back here and share your solution, I am look forward to it. – Lee Duhem Mar 03 '14 at 06:25

0 Answers0