For test I have made a trivial Java program that prints the java version
and directory from the System properties:
public class JavaTest
{
public static void main(String[] argv)
{
System.out.println(System.getProperty("java.home"));
System.out.println(System.getProperty("java.version");
}
I compile it with a low version of javac to ensure compatibility with manyQuote:}
JVMs:
$ PATH=/usr/java1.1/bin:$PATH javac JavaTest.java
Make the executable jar:
$ echo 'Main-Class: JavaTest' > manifest
$ jar cmf manifest JavaTest JavaTest.class
$ chmod +x JavaTest
When I execute it using the java command it uses the JVM of the first
java on the PATH - exactly as expected:
$ java JavaTest
/opt/jdk1.5.0/jre
1.5.0
The JVM is also confirmed by:
$ java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64) Java
HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
When I execute the jar I get what I expect:
$ ./JavaTest
/opt/jdk1.5.0/jre
1.5.0
If I change the PATH so another JVM is first I get unexpected results:
$ PATH=/usr/java1.2/bin:$PATH java -version
java version "1.2.2"
Solaris VM (build Solaris_JDK_1.2.2_10, native threads, sunwjit)
$ PATH=/usr/java1.2/bin:$PATH java JavaTest
/usr/java1.2/jre
1.2.2
$ PATH=/usr/java1.1/bin:$PATH java -version
java version "1.1.8"
$ PATH=/usr/java1.2/bin:$PATH ./JavaTest
/opt/jdk1.5.0/jre
1.5.0
$ PATH=/usr/java1.1/bin:$PATH ./JavaTest
/opt/jdk1.5.0/jre
1.5.0
With another machine:
$ java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01) Java
HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
$ ./JavaTest
/usr/java1.2/jre
1.2.2
If I compile with java v1.5 it still execs an old version which duly fails.
"truss -ef ./JavaTest" shows that it is execve(2) executing the jar file,
it also shows the PATH active for execve, but in choosing a JVM execve is
not using the PATH.
Finally the question: How does execve decide which JVM to use when
executing a jar file?