Install Java

You download the .tar.gz from the Oracle site to the machine and then unpack it in the correct directory. For example

$ mkdir -p /opt/java/7u80
$ tar -C /opt/java/7u80 -xovzf /tmp/jdk-7u80-linux-x64.tar.gz —strip-components 1

 

We install all our java versions into a subdirectory of /opt/java, matching the version number, and create a symlink for which version is the actual active one. So for example:

$ ls -l /opt/java
lrwxrwxrwx 1 root root    5 May 12 08:37 7 -> 7u80/
drwxr-xr-x 8 root root 4096 May 12 07:40 7u79
drwxr-xr-x 8 root root 4096 May 12 08:36 7u80
lrwxrwxrwx 1 root root    5 May 12 07:42 8 -> 8u45/
drwxr-xr-x 8 root root 4096 May 12 08:36 8u45

 

Create java function

Next, we create an initialization file /etc/profile.d/java.sh which creates a function with the name “java”. Functions take precedence over files when run. So we will set some environment variables to select the correct java version and then call the “real” java binary at the end

#!/bin/bash

export JAVA_VERSION=8

# -----
#   override java command to allow setting the desired version at runtime
# -----
java() {(
    export JAVA_HOME="/opt/java/$JAVA_VERSION"
    export PATH="$JAVA_HOME/bin:$PATH"
    JAVA="$(which java)"
    [[ -n $JAVA ]] && "$JAVA" "$@"
)}

The first JAVA_VERSION is the default. So in this case the default is java 8. After that we define the function “java” which sets the $PATH variable and then uses “which” to find the binary, which will result in the one we just prepended our $PATH with. Also note that the function creates a subshell (by using the round braces around the body). This is done so we don’t pollute our existing environment when running the function. If we don’t do that, every time we call the “java” function, something gets prepended to our $PATH variable, which might mask issues.

 

Example usage

We can now select the java version we would like at runtime. So all apps can choose which version of java they are runnig with just by setting the JAVA_VERSION environment variable like this:

$ java -version; echo $?
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
0

$ JAVA_VERSION=7 java -version; echo $?
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
0

$ JAVA_VERSION=8 java -version; echo $?
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
0

$ JAVA_VERSION=9 java -version; echo $?
/usr/bin/which: no java in (/opt/java/9/bin:/sbin:/bin:/usr/sbin:/usr/bin)
1

If you are familiar with ruby, this is similar to how you can use rbenv to select the ruby version by setting the RBENV_VERSION environment variable

Enjoy!