Technical details for https://stackoverflow.com/a/44169445/6730571
On a base system, /usr/bin/java
is a symlink that points to /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
, which is an Apple wrapper tool that locates and executes the actual java
.
(Do not touch anything in those 2 system directories. It should actually be impossible due to "System Integrity Protection" anyway.)
If you don't have Java installed, attempting to execute java
will open a dialog that invites you to install it.
If you install a JDK from Oracle or OpenJDK pkg download, it goes to /Library/Java/JavaVirtualMachines
(1), and java
will find it.
When you have several of them, you can use /usr/libexec/java_home
as explained in other answers to help set $JAVA_HOME
for current shell.
If $JAVA_HOME
is set, and points to a valid JDK, Apple's java
wrapper will use it.
But how do we chose the default version, the one that executes without setting $JAVA_HOME
?
The old "Java Preferences pane" used to allow exactly that, but it does not exist anymore since 10.8.2.
By default, it seems the wrapper checks all JREs under /Library/Java/JavaVirtualMachines
(2) and runs the one with highest version (3).
I don't want that, if the latest is too "cutting edge" (e.g. JDK9 at the moment breaks groovyConsole
& other tools).
So, for example, to exclude JDK9 from consideration by system java wrapper, rename /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Info.plist
to Info.plist.disabled
.
(Editing the file also works, if you know how to convert to xml with plutil
, the relevant key is JVMVersion
: when I changed it from 9
to -9
or anything that is lower than 1.8.0_131
it was considered "lower" by the wrapper).
As far as I can tell it does not affect anything else. Yes, if I point $JAVA_HOME
to that JDK9 it does still work.
There might be an undocumented way to configure this (old versions used to read $HOME/Library/Preferences/java_home.plist
but that does not seem to be the case anymore).
(To be continued... ?)
(1) And also overwrites /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/
. Apparently this is the one that the new Preferences pane will launch -- this is the only exception I found to my solution: that thingy will still use JDK9 (latest I installed), but no other Java application does.
(2) To find this I used opensnoop
and followed what happened when executing java -version
. That gave clues about which files to check, and upon investigating I found that I was not alone :) Lots of clues, but sadly no exploitable conclusion on that page. I think the guy was using a pre-ElCapitan macOS.
Also used "verbose" mode for java launcher:
$ JAVA_LAUNCHER_VERBOSE=true java -version
2017-05-24 23:15:14.064 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///Users/asmithee/Library/
2017-05-24 23:15:14.065 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///Users/asmithee/Developer/
2017-05-24 23:15:14.065 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///Library/
2017-05-24 23:15:14.066 java[15602:731042] [JVM Detection] AddJVMsFromSampledFile: Checking for a JVM at: libjli.dylib -- file:///Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/MacOS/
2017-05-24 23:15:14.066 java[15602:731042] [JVM Detection] Match: Could not find constraint for JVMMaximumSystemVersion
2017-05-24 23:15:14.066 java[15602:731042] [JVM Detection] Match: Could not find constraint for JVMMaximumFrameworkVersion
2017-05-24 23:15:14.066 java[15602:731042] [JVM Detection] AddJVMsFromSampledFile: JVM has capabilities: (
CommandLine
)
2017-05-24 23:15:14.067 java[15602:731042] [JVM Detection] AddJVMsFromSampledFile: Checking for a JVM at: libjli.dylib -- file:///Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/MacOS/
2017-05-24 23:15:14.067 java[15602:731042] [JVM Detection] Match: Could not find constraint for JVMMaximumSystemVersion
2017-05-24 23:15:14.069 java[15602:731042] [JVM Detection] Match: Could not find constraint for JVMMaximumFrameworkVersion
2017-05-24 23:15:14.070 java[15602:731042] [JVM Detection] AddJVMsFromSampledFile: JVM has capabilities: (
CommandLine
)
2017-05-24 23:15:14.070 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///Developer/
2017-05-24 23:15:14.070 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///System/Library/
2017-05-24 23:15:14.070 java[15602:731042] [JVM Detection] AddJVMsFromLibraryPath: Scanning: file:///Developer/
available JVMs:
1.8.0_131, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home
1.8.0_74, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_74.jdk/Contents/Home
obtained version: "1.8.0_131"
set preferred architecture to: "x86_64"
about to exec: "/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home"
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
The "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/" is the default JRE for other installed softwares. In my case, I need to remove the JavaAppletPlugin.plugin folder, and reinstall java8 to get everything work, and make java8 as my default JRE system-widely.