by Matt Johnson - Sun 22 May 2016
Tags: #macbook

The purpose of this article is to illuminate how Java is installed and accessed on Mac OS X 10.5 versions and later. If you execute which java this will output /usr/bin/java.

This is not where Java resides, it is a symbolic link to /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

And confusingly enough, this is also not where Java resides. Files contained in /System tend to be Apple specific and not 3rd party. The second clue, as pointed out by Stack Overflow user bdash [1], are files in: /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands are on the order of 10 bytes in size. The real Java executable is bigger than that!

Dynamic Tracing

bdash gives the following command to run</a>: sudo dtrace -n 'syscall::posix_spawn:entry { trace(copyinstr(arg1)); }' -c "/usr/bin/java -version"

This outputs:

dtrace: description 'syscall::posix_spawn:entry' matched 1 probe dtrace: pid 712 has exited CPU ID FUNCTION:NAME 0 629 posix_spawn:entry /Library/Java/JavaVirtualMachines/jdk1.7.0_65.jdk/Contents/Home/bin/java

This suggests the Java program resides in


and is indeed correct. Also, to confirm that I have one JDK version, I observe that my directory /Library/Java/JavaVirtualMachines only contains one directory named jdk1.7.0_65.jdk Multiple JDK versions are allowed and will reside in /Library/Java/JavaVirtualMachines/

The next question is, how are multiple versions managed? And the answer is java_home

Java Home

Since Mac OS X 10.5, Apple has provided a tool called java_home. Its function is to dynamically find the Java version a user specifies in Java Preferences [2]. It returns the home path of the current JDK in use. I run this program with help flag:

/usr/libexec/java_home --help

And discover the --verbose flag. It tells me the full list of JVM architectures I have on my machine. When I run this with this flag on my machine (Macbook OS X 10.10.3) I get the following output:

Matching Java Virtual Machines (1): 1.7.0_65, x86_64: "Java SE 7" /Library/JavaVirtualMachines/jdk1.7.0_65.jdk/Contents/Home

This confirms what I observed earlier in /Library/Java/JavaVirtualMachines, that I only have one JDK version. Just like /usr/bin/java, java_home is a symbolic link to a file that resides in:


By the way, /usr/libexec is supposed to a folder that contains binaries meant to be run by other programs (i.e., not users) [3].

Java Applet

There's one last Java version sitting around that should be explained as well. Consider:

/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java

It's not a symbolic link nor a binary that redirects to another file. What is it? The path makes it clear: it's used by Safari when it executes a Java applet. On my machine, it has a newer build. It's a JRE and to the best of my knowledge, it only allows one JRE version to be installed.


Now that we better understand how Java is accessed on the Mac, we'd like to set the environmental variable JAVA_HOME. Modify your ~/.bash_profile file:

JAVA_HOME=$(/usr/libexec/java_home) PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME

Using java_home instead of hard-coding a path, will return the path of the Java home directory. We add it to our path variable and finally, export the JAVA_HOME for use as an environmental variable

As a final note, apparently for versions earlier than 10.5, Apple recommends using the fixed path of /Library/Java/Home [2].