Installing Multiple Versions of Java on Mac

macOS allows installing different versions of Java.

The version of Java being used is determined by setting the JAVA_HOME system variable.

One way to do this is through a combination of using the java_home executable and aliases, but this comes with some pitfalls you need to be aware of.

java_home Executable

java_home executable:

The java_home executable has access to JDKs & JREs installed here:

Command to list all JDKs/JREs in the JavaVirtualMachines directory:
/usr/libexec/java_home -V

Let's say a user has both Java 8 and Java 11 installed. The following aliases could be created in the .bash_profile to allow quickly switching between the versions:
alias j11="export JAVA_HOME=$(/usr/libexec/java_home -v 11); java -version"
alias j8="export JAVA_HOME=$(/usr/libexec/java_home -v 1.8); java -version"


While the above method works well when running Java from the command line, it will not work well for any application launched in the OS. By default, the OS will run the newest version of Java in the JavaVirtualMachines directory. This is a problem if the app cannot run on a newer version of Java. Furthermore, there's no way to force java_home to choose a specific version as the default that would be returned by running the java_home command by itself.

A specific example of this problem is trying to run NetBeans 8.2 when Java 11 is installed. NetBeans 8.2 cannot run on Java 11.

Alternative to Using java_home Exclusively

Since JDKs and JREs are self contained, they do not need to be installed in the JavaVirtualMachines directory. The exception is that any app run by macOS that needs to run on Java will expect to find and run the newest version of it in JavaVirtualMachines. But if you simply want to develop in a different version of Java or want to run a Java program from the command line with a different version, you could install those other versions anywhere.

In particular, IDEs make running different versions for development very easy, as you just tell the IDE which JDK to use. And they do not need the JDKs installed anywhere in particular.

If you'd still like to create aliases to easily change Java versions in the shell, you can simply provide the path to the Home directory for the versions no longer stored in the JavaVirtualMachines directory. If, in the example above, Java 11 is moved into a directory in the user's home directory, the aliases could look like the following:

alias j11="export JAVA_HOME=/Users/mrr39/java/jdk-11.0.1.jdk/Contents/Home; java -version"
alias j8="export JAVA_HOME=$(/usr/libexec/java_home -v 1.8); java -version"

With this set up the "system" Java version remains Java 8, which will be used by all .app Mac applications. But you can still change to Java 11 in the bash shell.

Other Alternatives

It should also be possible to write wrapper scripts around .app applications that will force the version of Java the application will use. It may also be possible that there is a way to configure the app to use a specific version of Java.

This alternative could become necessary should multiple macOS apps require different versions of Java.

JDKs vs JREs

Java releases are moving away from Java Run Environments (JRE) in favor of exclusively releasing Java Development Kits (JDK), since releasing both results in a lot of duplication. JDKs are required if you want to develop Java programs. The JRE is simply a stripped down version of the JDK which has the Java Virtual Machine (JVM) required to run Java programs.

For the java_home executable, it can handle either JREs or JDKs, since all it's looking for is the path to the Home directory, which both JDKs and JREs contain.

-- MichaelRyan - 03 Jan 2019
Topic revision: r2 - 27 Jun 2022, MichaelRyan
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding CLASSE Wiki? Send feedback