Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

This is not a naïve question; please bear with me.

Can someone tell me how an invocation of /usr/bin/java on an Apple MacBook Pro from mid-2010 with both the Apple JDK and the Oracle 1.8.0 JDK installed results in the Oracle 1.8.0 JDK being found and used?

Please note that my version of the Apple-installed JDK 1.6 is recent enough that the Java Preferences application has been removed by them, so that does not factor into the determination of which Java VM to use.

Furthermore please note that /usr/libexec/java_home is not invoked (by me, anyway) in any of my examples below.

OK, here we go.

Oracle's JDK 1.8 gets installed into /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/. Fine.

/usr/bin/java, which is under Apple control, is a symbolic link pointing to /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java. (/System/Library/Frameworks/JavaVM.framework/Versions/Current is a symbolic link pointing to /System/Library/Frameworks/JavaVM.framework/Versions/A (a directory), so, by extension, /usr/bin/java after symbolic link resolution points to /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java.)

/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java is not a symbolic link. It is an executable. Its last modified timestamp is quite old, probably corresponding to when I installed JDK 7 some time ago. In any event, it does not correspond to the date on which I installed JDK 8.

/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/bin/java is not equal in size to /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java. It is not a symbolic link either. Its last modified timestamp corresponds to when I installed JDK 8. These two are different programs.

Nevertheless, invoking either of these java variants with a -version argument yields a version string identifying them as 1.8.

How is the semantic link established between /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java and /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/bin/java, given that neither is a symbolic link to the other?

Secondly, who "owns" /System/Library/Frameworks/JavaVM.framework/Versions/A: Oracle or Apple?

Furthermore, consider the following output, especially the argv[0] setting identifying /usr/bin/java as the program name, even though I never typed that (line 13 in the output below):

Laird-Nelsons-MacBook-Pro:repository ljnelson$ env _JAVA_LAUNCHER_DEBUG=true /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java -version
----_JAVA_LAUNCHER_DEBUG----
Launcher state:
    debug:on
    javargs:off
    program name:java
    launcher name:java
    javaw:off
    fullversion:1.8.0-b132
    dotversion:1.8
    ergo_policy:DEFAULT_ERGONOMICS_POLICY
Command line args:
argv[0] = /usr/bin/java
argv[1] = -version
JRE path is /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre
jvm.cfg[0] = ->-server<-
jvm.cfg[1] = ->-client<-
69 micro seconds to parse jvm.cfg
Default VM: server
Does `/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.
----_JAVA_LAUNCHER_DEBUG----
Launcher state:
    debug:on
    javargs:off
    program name:java
    launcher name:java
    javaw:off
    fullversion:1.8.0-b132
    dotversion:1.8
    ergo_policy:DEFAULT_ERGONOMICS_POLICY
Command line args:
argv[0] = /usr/bin/java
argv[1] = -version
JRE path is /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre
jvm.cfg[0] = ->-server<-
jvm.cfg[1] = ->-client<-
33 micro seconds to parse jvm.cfg
Default VM: server
Does `/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/server/libjvm.dylib' exist ... yes.
JVM path is /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/server/libjvm.dylib
2242 micro seconds to LoadJavaVM
JavaVM args:
    version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 4
    option[ 0] = '-Dsun.java.launcher.diag=true'
    option[ 1] = '-Dsun.java.launcher.diag=true'
    option[ 2] = '-Djava.class.path=.'
    option[ 3] = '-Dsun.java.launcher=SUN_STANDARD'
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
share|improve this question
    
JDK 7 is Oracle as well - I suspect they read a configuration set in System Preferences –  Mark Apr 16 at 21:59
1  
    
@Mark, thanks; it is; they do not. @Rene, thank you for the cross-link. I've since found that both /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java and /usr/libexec/java_home end up invoking a private framework called JavaLaunching, which is undocumented. Running strings on it suggests that it does a simple stupid scan (!) of /Library/Java/JavaVirtualMachines and then uses some (undocumented) heuristic to figure out which is the most recent. Ugly and surprising. –  Laird Nelson Apr 16 at 23:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.