Managing Multiple Java Versions on Mac

I've recently seen a lot of folks struggling with this, so I figured I would document the approach I'm using.

Firstly, the best way to install most programs on the Mac is obviously Homebrew. However, whereas Homebrew works fine to install OpenJDK versions of Java, the Oracle versions are not available on Homebrew (or any of the Casks) as I write this post. So, you will need to download the installer from Oracle's website (requires registration).

Make sure you pay attention to whether you need the JRE (Java Runtime Environment) or JDK (Java Development Kit). The JRE is sufficient if all you need to do is run a Java application or another application that runs on the Java VM. The JDK is needed if you need to compile or build Java programs.

JREs and JDKs are designed to allow multiple versions to co-exist peacefully on the same machine. If the installer asks you to uninstall an older version, that's usually a recommendation aimed at preventing you from continuing to use an older version that has security vulnerabilities. But it is usually just a recommendation asking you to go to a more recent update for that version.

Some folks recommend using tools like jEnv and SDKMan to manage their Java versions. These tools have some good features. For example, jEnv will allow you to set a Java version for a specific folder and then automatically switch to that Java version when you go to that folder in the terminal. However, the challenge with using too many tools is that after a while you forget how the magic works and have to remember how to use the tool again. Therefore, I prefer to use the lower level approach based on basic tools described below so that when things go wrong I know exactly where to look.

After you've installed the Java versions you want to have available on your Mac, set up a section as follows in your ~/.bash_profile with a unique environment variable pointing to each Java version location.


The version reference in the above snippet only needs to be as granular as needed to be unique. So, since there is only one v14 install, -v14 is sufficiently granular. However, since there are two different v8 installs, the version references need to be very granular (in this case all the way down to the update level, i.e. 242 for OpenJDK versus 251 for Oracle).

In order to get a list of the Java versions installed on your Mac, run the following in a terminal session (I recommend using iTerm2 instead of the out-of-the-box Mac terminal, although either one will do).

/usr/libexec/java_home -V

This will list out all of your Java versions. Use this information to set up the environment variables as shown above. The above command will also tell you the exact install location for each Java version so that you can point your IDE such as Eclipse to the right Java version as needed.

For example, /Library/Java/JavaVirtualMachines/openjdk-14.jdk/Contents/Home

Once, that's done, set up a section in your ~/.bash_profile with an alias you can use for switching to each Java version. An alias is a shorthand command that executes the full command.

So, when you issue the command java8, the OS actually executes the command export JAVA_HOME=$JAVA_8_HOME thereby setting the JAVA_HOME environment variable that controls which version of Java runs when you run the command java. To see all of the currently set environment variables, run the command set.


Run the following command to load the changes to your ~/.bash_profile

source ~/.bash_profile

Now you can switch to Java 8 (for example) just by running the command java8.

I usually execute the alias for my "default" Java version inside my ~/.bash_profile. Subsequently, I only need to change it as needed. But note that when you change your Java version by executing an alias, that change is only effective for that terminal session and does not carry over to other terminal sessions.

Since I have a bunch of customizations like these in my ~/.bash_profile, I keep my actual .bash_profile file in Dropbox and have a symbolic link to it sitting in my home directory where Mac looks for it.

To create such a symbolic link you just type the following.

ln -s ~/Dropbox/LinkedFiles/.bash_profile ~/.bash_profile

Note: In the case of Python, I don't use the same approach. Because it's not just a question of managing Python versions but also the versions of all the libraries you typically end up using with a Python program. And, as far as I know, there isn't a Maven-like tool for Python to manage program dependencies. So, instead, I use Docker containers to isolate the specific Python version and library versions for a specific program from my machine's native host environment. It is especially important to be careful with your Python usage on a Mac because the Mac natively comes installed with and uses Python 2. Although I don't have any first-hand experience of this, it seems some Mac apps might be using the pre-installed Python and might start misbehaving if you make changes to the pre-installed Python version or related libraries.

Comments

Popular posts from this blog

Milwaukee Appliance Hand Truck

Utility trailer buying guide

My Experiments with the PICAXE 08M2+