How does /usr/bin/java work on Mac?

Solution 1:

I can't fully answer your question but I have a few practical clues I can share.

TL:DR;

I think that /usr/bin/java is a proxy application, part of MacOS, that calls the java command in the current java installation as defined by JAVA_HOME env var.

And this is the same for all the java related commands in /usr/bin

More details

I have installed (manually, by unzipping the openjdks into /Library/Java/JavaVirtualMachines/) many versions of Java, and just by setting a different JAVA_HOME, the version switches:

$ JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home && java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)

$ JAVA_HOME=/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home/ && java -version
openjdk version "11.0.11" 2021-04-20 LTS
OpenJDK Runtime Environment Corretto-11.0.11.9.1 (build 11.0.11+9-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.11.9.1 (build 11.0.11+9-LTS, mixed mode)

$ JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-16.0.1.jdk/Contents/Home/ && java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+9-24)
OpenJDK 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)

All the Java commands in /usr/bin have the same size (136Kb in my case):

$ ll -h /usr/bin/ja*
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/jar
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/jarsigner
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/java
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javac
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javadoc
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javah
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javap
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javapackager
-rwxr-xr-x  1 root  wheel   136K Jan  1  2020 /usr/bin/javaws

Actually, many files in /usr/bin are the same:

$ find /usr/bin | sort | xargs md5 | grep d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/appletviewer) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/apt) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/extcheck) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/idlj) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/jar) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/jarsigner) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/java) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/javac) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/javadoc) = d50afbfa4f5d05e8db7ad88c30390888
MD5 (/usr/bin/javah) = d50afbfa4f5d05e8db7ad88c30390888
.
.
.

In "System Information.app > Software > Installation" I don't find any specific installation occurred around Jan 1 2020, from the same I see I installed Catalina on 2019-10-12 and Big Sur on 2020-12-04 (all files in /usr/bin have date Jan 1 2020).

Also pkgutil doesn't tell me to which package installation the /usr/bin/java commands belongs:

$ pkgutil --file-info /usr/bin/java
volume: /
path: /usr/bin/java

I believe it's part of MacOS and was installed (or updated) by Big Sur.

Let me know if I missed anything or have more info for a clearer picture :-)

Solution 2:

The most complete answer I've found is this Stack Overflow answer:

https://stackoverflow.com/questions/21964709/how-to-set-or-change-the-default-java-jdk-version-on-macos/44169445#44169445

In summary, /usr/bin/java finds all of the JVMs under /Library/Java/JavaVirtualMachines and ~/Library/Java/JavaVirtualMachines and points to the latest JVM that has Contents/Info.plist. If you rename that file in a JVM to, say, Contents/Info.plist.disabled, then /usr/bin/java will not pick it.