Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.

Switching Java versions on the command line

The Java 9 release is coming up and more and more developers will download and try it out soon. However, you probably won’t migrate all your projects to it yet and will want to maintain several versions of the JDK on your machine.
It creates a common problem with how to switch the version of Java you’re using so that you can reliably get the right answer when you run the command:

java -version

In this post, I want to share my setup to switch the active JDK version on the command line. Note, I’m use a Mac, and the scripts in this post will work on a Mac and, perhaps, on some Linux machines. If you have a good recipe on how you switch Java versions on the command line on Windows, please share with the community in the comments.

Let’s get to it then. When you download a new JDK release it comes as an installer, so you double click it, click the “Next” button necessary amount of times, and it puts the files somewhere on the filesystem. Or you do it manually.

To run Java command line utilities successfully, including the java command, you need two things:

  • a $JAVA_HOME environment variable set.
  • a java executable on the $PATH.

Here’s how I do it, and if I’m not mistaken I took this approach from Neeme.

We’ll utilize the ~/.bashrc file to declare the functions we’ll use later. So open it in your favorite editor, something line atom ~/.bashrc would do.

The first function, which we’ll use later to set the JDK versions is setjdk.

# set and change java versions
function setjdk() {  
  if [ $# -ne 0 ]; then  
    removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'  
    if [ -n "${JAVA_HOME+x}" ]; then  
      removeFromPath $JAVA_HOME  
    fi  
    export JAVA_HOME=`/usr/libexec/java_home -v $@`  
    export PATH=$JAVA_HOME/bin:$PATH  
  fi  
}

This script finds the correct $JAVA_HOME location by using the /usr/libexec/java_home utility passing the argument string as a parameter. Then it exports the $JAVA_HOME and the correct $PATH values.

Since you’d like to switch the versions back and forth, we also include the code to clean up the $PATH, to remove the current version of the $JAVA_HOME/bin from it.

Here’s what the removeFromPath function looks like. Oh, and don’t forget to add it to the ~/.bashrc too.

removeFromPath () {
    export PATH=$(echo $PATH | sed -E -e "s;:$1;;" -e "s;$1:?;;")
}

What it does is pretty self-explanatory, albeit quite cryptic. It uses sed to replace the argument value with an empty string. Essentially, it removes whatever you pass it from the $PATH.

Now with these functions in place you can set the desired versions of Java as active. Save the ~/.bashrc file. If you’re doing it in a terminal session, reload it with the source ~/.bashrc.
Try now setting your default Java to one of the different Java versions you currently have installed.

→ setjdk 1.8

→ java -version
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)

→ setjdk 9

→ java -version
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+174)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+174, mixed mode)

It should work. If it doesn’t, debugging this small shell script is quite straightforward (hint: most probably it’s a typo, check yourself), so we’ll omit the debugging guide from this post for brevity.

Oh, also, it might be a good idea to add the setjdk 1.8 line to the ~/.bashrc, so all your sessions start with a predetermined JDK version.

Hope you found this post useful, if you’re running Windows, either 0. check the comments, as someone might have shared a good recipe to handling multiple Java versions on the command line for Windows, 1. Check StackOverflow or 2. Make better life choices.


Read next: