12

I found /usr/bin/java linked to /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java. And its file content is different from /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java. But when I type /usr/bin/java -version it prints

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) 

So I'm curious about the implementation of /usr/bin/java and wondering why it can always point to the latest version of my JavaVirtualMachines?

0

2 Answers 2

16

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 :-)

2
  • 1
    On my installation, the various Java commands in /usr/bin/ are in fact hard linked to one another. 31 in total, though the hard link count is 52 and I'm looking for where the other 21 might be.
    – Menachem
    Aug 15, 2022 at 22:26
  • On my system, the total hard link count is also 52, but 51 of them are in /usr/bin/ and one is /usr/libexec/java_home. Sadly, pkgutil --file-info ... doesn't say about any of them from which package/app they came from
    – clausavram
    Aug 3, 2023 at 9:24
8

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.

2
  • so I knew where my java home is but I actually curious how the /user/bin/java linked to that cause ➜ ~ ls -l /usr/bin/java -rwxr-xr-x 1 root wheel 168432 7 Feb 08:22 /usr/bin/java ➜ ~ echo "$JAVA_HOME" ➜ ~ (my JAVA_HOME env is empty), and /usr/bin/java is neither a symlink or raw text
    – HoaPhan
    Mar 15, 2022 at 2:02
  • I think /usr/bin/java is an actual program, not a symlink.
    – James Lin
    Apr 2, 2023 at 16:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .