Managing multiple Java versions in Linux

Jan Barrera
2 min readJul 23, 2020

I had a recent trouble managing multiple Java versions installed in my Linux machine. I had Java openjdk versions 8 and 11 which were installed on separate occasions. Complications arise when I started Java development as java, javac, and mvn were pointing to different jdk packages.

java -version returns version 11

$ java -version
openjdk version "11.0.7" 2020-04-14

javac and mvn returns version 8

$ javac -version
javac 1.8.0_222
$ mvn -version
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 1.8.0_222, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-1.fc31.x86_64/jre

A quick check on where each links are pointed.

$ readlink $(readlink $(which java))
/usr/lib/jvm/java-11-openjdk-11.0.7.10-1.fc31.x86_64/bin/java
$ readlink $(readlink $(which javac))
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-1.fc31.x86_64/bin/javac

I think the easiest way to manage multiple versions of Java (or Python, or any other application in Linux) is to use the alternatives tool. The alternatives tool can create, remove, and maintain the symbolic links of different systems.

$ alternatives --help
alternatives version 1.11 - Copyright (C) 2001 Red Hat, Inc.
This may be freely redistributed under the terms of the GNU Public License.
usage: alternatives --install <link> <name> <path> <priority>
[--initscript <service>]
[--family <family>]
[--slave <slave_link> <slave_name> <slave_path>]*
alternatives --remove <name> <path>
alternatives --auto <name>
alternatives --config <name>
alternatives --display <name>
alternatives --set <name> <path>
alternatives --list
alternatives --remove-all <name>
alternatives --add-slave <name> <path> <slave_link> <slave_name> <slave_path>
alternatives --remove-slave <name> <path> <slave_name>
common options: --verbose --test --help --usage --version --keep-missing
--altdir <directory> --admindir <directory>

I wanted the default Java to be version 11 so I used alternatives to configure javac to point to Java 11 openjdk.

$ sudo alternatives --config javacThere are 2 programs which provide 'javac'.Selection    Command
-----------------------------------------------
* 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-1.fc31.x86_64/bin/javac)
+ 2 java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.7.10-1.fc31.x86_64/bin/javac)
Enter to keep the current selection[+], or type selection number: 2

Checking javac now yields what I want.

$ javac -version
javac 11.0.7

Maven uses JAVA_HOME environment variable as indicator on what Java jdk to use. To be consistent, I want JAVA_HOME to point to whatever Java version I select.

$ export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink $(which java)))))

Add this to ~/.bashrc or ~/.bash_profile so that the value will stick even after reboot.

$ mvn -version
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 11.0.7, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-11-openjdk-11.0.7.10-1.fc31.x86_64

--

--