Working with Different Java Versions

¡Hola!

Happy 2021! ✨ It’s already been a month and a half, but it still counts, right? 😊

When you are with Java, many circumstances may drive the need to work with its different versions. For example:

  • You may still have some projects that require Java 8.
  • You may have some projects that have been migrated to the latest Java LTS (as of this writing): Java 11.
  • You may be staying up to date and have some projects that use Java 15.

I will share the setup I use on macOS to switch between Java Versions per project in 3 steps:

  1. Installation
  2. Manually switching Java versions
  3. Automagically switching Java versions

Installation

To install different Java versions I use Homebrew and these are the steps:

  1. Update the formulae and Homebrew itself: brew update

  2. Look for the Java Version you wish to install, I use three commands:

1
brew search 'jdk'

The following, that is a more extensive search and where you’ll see more results:

1
brew search --desc 'java'

You can also refine your search more once you get some names of formulae, for example:

1
brew search openjdk

will give you many more specific results.

  1. Choose the formulae, or the cask to install. I like to some information before installing using the following command:
1
brew info <formulae_or_cask>

For example for:

1
brew info adoptopenjdk

the output would be:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
adoptopenjdk: 15.0.2,7
https://adoptopenjdk.net/
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/adoptopenjdk.rb
==> Name
AdoptOpenJDK Java Development Kit
==> Description
None
==> Artifacts
OpenJDK15U-jdk_x64_mac_hotspot_15.0.2_7.pkg (Pkg)
==> Caveats
More versions are available in the AdoptOpenJDK tap:
  https://github.com/AdoptOpenJDK/homebrew-openjdk

  brew tap adoptopenjdk/openjdk

==> Analytics
install: 4,655 (30 days), 13,619 (90 days), 53,071 (365 days)
  1. Install the formulae. For example, the following command would install OpenJDK 15:
1
brew install adoptopenjdk

And the following would install OpenJDK 11

1
brew install openjdk@11

Manually switching between versions

Now that you have different versions installed, a quick and easy method to manually switch between versions is to:

  1. Export different JAVA_HOME_X env vars in the .bash_profile file of your home directory, per Java version. For example:
1
2
3
export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_15_HOME=$(/usr/libexec/java_home -v15)
  1. Add aliases to set the JAVA_HOME env var to one of the variables that you set before. For example:
1
2
3
4

alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java15='export JAVA_HOME=$JAVA_15_HOME'

You can then set a default Java version by adding for example: java8 to the .bash_profile file. When you want to switch to a different Java version, all you have to do is call one of the aliases you defined. For example, given that you set java8 to be the default, when we run:

1
java -version

the output would be:

java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

Then, when we want to switch to Java 15, we run:

1
java15

and when we run:

1
java -version

The output would be:

openjdk version "15.0.2" 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 15.0.2+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15.0.2+7, mixed mode, sharing)

Automagically switching between versions

To have the Java version automagically switched between projects, I have used jEnv. From their website:

jEnv is a command line tool to help you forget how to set the JAVA_HOME environment variable

The first step then, would be to install jEnv on your machine. You can follow the instructions on their website. For macOS, you can install jEnv via Homebrew:

1
brew install jenv

Then, add the following to your .bashrc file to initialize jEnv:

1
echo eval "$(jenv init -)" >> /Users/lalyta/.zshrc

Next, we need to tell jEnv were to find the different JDKs by using jenv add. For macOS, the following folder includes the JDKs installed on your machine: /Library/Java/JavaVirtualMachines. So, for JDK 15, we would run:

1
jenv add /Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home/

And the output would be:

1
2
3
4
openjdk64-15.0.2 added
15.0.2 added
15.0 added
15 added

Then, we can add JDK 8:

1
jenv add /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/

When we run:

1
jenv versions

the output is:

1
2
3
4
5
6
7
8
* system (set by /Users/your_user/.jenv/version)
  1.8
  1.8.0.91
  15
  15.0
  15.0.2
  openjdk64-15.0.2
  oracle64-1.8.0.91

Then, go into the root directory of one of your projects and run:

1
jenv local <jdk_version>

For example:

1
jenv local 1.8

This will create a .java-version to the root directory of your project with 1.8 as the content.

When switching projects, jEnv will take care of switching versions 🎉

So, when you go to the terminal and change directory to the root folder of your project and run:

1
java -version

the output would be:

1
2
3
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

And, if we were to change the content of the .java-version file and replace 1.8 with 15, and then go to the terminal again and run:

1
java -version

the output would be:

1
2
3
openjdk version "15.0.2" 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 15.0.2+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15.0.2+7, mixed mode, sharing)

Magic ✨

One more thing

I personally prefer to switch versions manually 😊, I check the Java version to use in the pom.xml file of the project. It helps me set my mind into the Java version I will be using and become more conscious about it. I guess this may be an issue if there are many, many projects to manage, but until now that has not been an issue for me, so I still use the manual method ☕.

Well, I hope this helps!

May the Force be with you, always! ✨