Developers and system administrators frequently work with projects requiring distinct Java Development Kit (JDK) versions—such as maintaining legacy Java 8 or Java 11 microservices alongside modern Spring Boot applications built on Java 17 or Java 21 LTS. Rather than uninstalling and reinstalling packages or manually rewriting PATH variables, Ubuntu provides a native system tool called update-alternatives to toggle between installed Java runtimes and compilers seamlessly.
How Debian Alternatives System Manages Java
Ubuntu uses symbolic links managed by the alternatives system to route generic commands (like /usr/bin/java) through /etc/alternatives/java to the actual binary located inside /usr/lib/jvm/. Each installed JDK package registers its binaries and man pages with a priority score, allowing automatic or manual switching.
Step 1: Check Currently Installed Java Versions
Before switching, verify which JDK and JRE packages are currently recognised on your Ubuntu machine:
update-alternatives --list java
This command outputs the absolute filesystem paths to all registered Java runtime executables, typically resembling:
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
/usr/lib/jvm/java-21-openjdk-amd64/bin/java
If you need to install additional versions via APT, run:
sudo apt update
sudo apt install openjdk-17-jdk openjdk-21-jdk
Step 2: Switch the Default Java Runtime (java)
To switch the active Java runtime environment interactively:
- Open your terminal and run:
sudo update-alternatives --config java - You will see an interactive table listing all available Java choices, their status (auto or manual), and priority numbers:
Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2111 auto mode 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode 2 /usr/lib/jvm/java-17-openjdk-amd64/bin/java 1711 manual mode 3 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2111 manual mode Press <enter> to keep the current choice[*], or type selection number: - Type the number corresponding to your desired version (for example,
2for Java 17) and press Enter.
Step 3: Switch the Java Compiler (javac)
Switching java alone updates the runtime engine but leaves the compiler pointing to your previous JDK. To align the compiler version with your runtime:
- Execute the alternatives configuration command for the compiler:
sudo update-alternatives --config javac - Select the matching number for your chosen JDK version and press Enter.
Step 4: Update the JAVA_HOME Environment Variable
Build automation tools such as Maven, Gradle, Ant, and IDE plugins read the JAVA_HOME variable rather than relying purely on the command path. Configure your system profile to resolve JAVA_HOME dynamically from your active alternative link:
- Open
/etc/environmentin Nano with sudo privileges:sudo nano /etc/environment - Append or update the
JAVA_HOMEpath to point to the base JDK directory corresponding to your selection:JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64" - Save changes with Ctrl + O and exit with Ctrl + X.
- Reload the updated environment variables into your current shell session:
source /etc/environment
Step 5: Verify the Active Java Environment
Confirm that both your runtime and compiler versions are synchronised and reporting the expected build versions:
java -version
javac -version
echo $JAVA_HOME
Your Ubuntu environment is now configured to build and execute Java applications against your chosen JDK version cleanly, without version conflicts or manual symlink manipulation.