How to Install OpenJDK 21 on Ubuntu

OpenJDK 21 is a Long-Term Support release of the free, open-source Java Development Kit. This version brings virtual threads, pattern matching for switch expressions, and record patterns to production environments. Released in September 2023, OpenJDK 21 receives community support through at least September 2031 and has proven itself in production deployments across enterprise environments. This guide covers two installation methods: Ubuntu default repositories for simplicity, and Eclipse Temurin for enterprise-quality builds with faster security updates. By the end of this guide, you will have OpenJDK 21 installed on Ubuntu with the ability to manage multiple Java versions and verify your installation.

Compare OpenJDK LTS Releases for Ubuntu

Selecting the right Java version affects long-term maintenance and access to language features. The table below compares current LTS releases available in Ubuntu’s default repositories, helping you choose based on your project’s requirements.

Java VersionLTS Support UntilChoose It WhenTrade-offs
OpenJDK 8December 2030 (community)Legacy applications, older frameworks like Spring 4.x, or vendor-certified deployments requiring Java 8Missing modern language features (no var, no records, no virtual threads); some libraries dropping Java 8 support
OpenJDK 11September 2027 (community)Enterprise applications, build servers, projects needing stable LTS with module system support and modern TLSLacks Java 25 features; some newer frameworks require 17+ as minimum
OpenJDK 17September 2029 (community)Spring Boot 3.x, Jakarta EE 10+, or workloads benefiting from records and sealed classesLacks virtual threads and scoped values from newer releases
OpenJDK 21September 2031 (community)High-concurrency applications using virtual threads, projects needing structured concurrencyScoped values still in preview; missing finalized features from Java 25
OpenJDK 25September 2033 (community)New projects, applications requiring finalized scoped values, key derivation APIs, or the latest stable LTS featuresNewest LTS release; verify framework compatibility before production migration

OpenJDK 21 is ideal for high-concurrency applications that benefit from virtual threads and teams wanting structured concurrency features. For new projects without legacy constraints, consider OpenJDK 25 for finalized scoped values and the latest stable language improvements. If your project relies on frameworks that have not yet certified Java 21 support, consider OpenJDK 17 as a stable alternative until your stack is ready.

Choose Your OpenJDK 21 Installation Method

This guide covers two installation methods. The table below compares each approach to help you decide which fits your needs:

MethodSourceUpdatesBest For
Ubuntu APTUbuntu ReposVia apt upgradeMost users; simpler setup, no external repositories needed
Eclipse TemurinAdoptiumVia apt upgradeEnterprise environments; AQAvit-verified builds with faster security patches

For most users, the Ubuntu APT method provides a well-maintained OpenJDK build that receives regular security updates. If you require builds that are TCK-certified and AQAvit-verified with potentially faster security patch releases, choose the Eclipse Temurin method instead.

The Ubuntu APT method works identically on Ubuntu 22.04 LTS, 24.04 LTS, and 26.04 LTS. The Eclipse Temurin method currently supports Ubuntu 22.04 and 24.04; Adoptium typically adds support for new Ubuntu releases within a few months of their launch.

Update Ubuntu Before OpenJDK 21 Installation

Before installing new software, refresh your package index to ensure you receive the latest available version and avoid dependency conflicts. Run the following commands to update your system:

sudo apt update
sudo apt upgrade

The first command downloads current package information from configured repositories, while the second upgrades installed packages to their newest versions. Depending on how recently you last updated, this process typically takes a few minutes.

Method 1: Install OpenJDK 21 via Ubuntu APT (Recommended)

Ubuntu’s default repositories include OpenJDK 21 packages, making installation straightforward without adding external sources. First, you can view the available packages to understand what’s available:

apt-cache search openjdk-21

This command lists all OpenJDK 21 related packages. You should see output similar to:

openjdk-21-jdk - OpenJDK Development Kit (JDK)
openjdk-21-jdk-headless - OpenJDK Development Kit (JDK) (headless)
openjdk-21-jre - OpenJDK Java runtime, using Hotspot JIT
openjdk-21-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless)
openjdk-21-source - OpenJDK Development Kit (JDK) source files
openjdk-21-doc - OpenJDK Development Kit (JDK) documentation
openjdk-21-demo - Java runtime based on OpenJDK (demos and examples)

The “headless” packages exclude graphical libraries and are designed for servers or CI/CD systems without a display. Therefore, if you are setting up a build server, container image, or any environment without a GUI, choose the headless variants for a smaller installation footprint.

Install JRE or JDK

Your choice depends on whether you need to run Java applications only or also develop them. The Java Runtime Environment (JRE) provides the minimum required to execute Java programs:

sudo apt install openjdk-21-jre

For development work, compiling source code, or using build tools like Apache Maven, install the full Java Development Kit (JDK) instead. The JDK package includes the JRE plus development utilities such as the Java compiler, debugger, and documentation tools:

sudo apt install openjdk-21-jdk

When in doubt, install the JDK. It includes everything from the JRE while adding development tools you may need later. The additional disk space is minimal compared to the flexibility gained.

Verify the Installation

Once installation completes, confirm Java is accessible by checking the installed version. OpenJDK 21 uses the double-hyphen version flag available since Java 9:

java --version

The output confirms OpenJDK 21 is installed and active:

openjdk 21.0.x 20xx-xx-xx
OpenJDK Runtime Environment (build 21.0.x+x-Ubuntu-x)
OpenJDK 64-Bit Server VM (build 21.0.x+x-Ubuntu-x, mixed mode, sharing)

Additionally, if you installed the JDK, verify that the Java compiler is available:

javac --version
javac 21.0.x

Method 2: Install Eclipse Temurin 21 via Adoptium APT

Eclipse Temurin is an enterprise-quality OpenJDK distribution from the Adoptium project. These builds are TCK-certified for Java compatibility and pass the AQAvit verification suite. This method adds the Adoptium APT repository to receive automatic updates.

Import the Adoptium GPG Key

First, download and install the Adoptium repository signing key. This key verifies that packages come from the official Adoptium infrastructure:

wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | \
  gpg --dearmor | sudo tee /usr/share/keyrings/adoptium.gpg > /dev/null

Add the Adoptium Repository

Next, create the repository configuration file using the DEB822 format. This script automatically detects your Ubuntu codename and architecture:

cat <<EOF | sudo tee /etc/apt/sources.list.d/adoptium.sources
Types: deb
URIs: https://packages.adoptium.net/artifactory/deb
Suites: $(. /etc/os-release && echo $VERSION_CODENAME)
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /usr/share/keyrings/adoptium.gpg
EOF

Once you add the repository, refresh your package index:

sudo apt update

Install Temurin 21

After refreshing the package index, install the Eclipse Temurin 21 JDK package:

sudo apt install temurin-21-jdk

Adoptium also provides temurin-21-jre if you only need the runtime environment without development tools.

Verify the Temurin Installation

After installation, verify that Temurin is accessible by checking the version:

java --version

The output should show the Temurin build identifier:

openjdk 21.0.x 2025-xx-xx
OpenJDK Runtime Environment Temurin-21.0.x+x (build 21.0.x+x)
OpenJDK 64-Bit Server VM Temurin-21.0.x+x (build 21.0.x+x, mixed mode, sharing)

Update Temurin to the Latest Version

Temurin receives updates through the Adoptium APT repository. To check for and install the latest version, run:

sudo apt update && sudo apt install --only-upgrade temurin-21-jdk

For automated update scripts, use the following bash pattern that checks whether an update is available before attempting the upgrade:

#!/bin/bash
# Update Temurin 21 if a newer version is available
sudo apt update
if apt list --upgradable 2>/dev/null | grep -q temurin-21-jdk; then
    echo "Temurin 21 update available, installing..."
    sudo apt install --only-upgrade temurin-21-jdk -y
else
    echo "Temurin 21 is already at the latest version."
fi

Manage Multiple Java Versions

Development environments often require multiple Java versions for different projects. Ubuntu’s update-alternatives system manages symlinks in /usr/bin/, allowing you to switch between installed versions without modifying PATH variables or manually creating symlinks.

Switch the Default Java Runtime

After installing multiple Java versions, you can switch between them using Ubuntu’s update-alternatives system. To view all installed Java versions and interactively select the system default, run:

sudo update-alternatives --config java

The command displays a numbered list of available Java installations along with their filesystem paths and priority values. If multiple Java versions are installed, the output looks similar to:

There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                         Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      auto mode
  1            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      manual mode
  2            /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 preferred Java version and press Enter. The asterisk marks the currently active selection. Once you switch versions, confirm the change by running java --version again.

Switch the Default Java Compiler

Similarly, when using multiple JDK versions, you should also switch the Java compiler to match the runtime. Compiling code with one Java version while running it on another can cause bytecode compatibility issues:

sudo update-alternatives --config javac

Select the same version number you chose for the runtime. Both commands return immediately to the shell prompt after making your selection.

Configure the JAVA_HOME Environment Variable

Build tools, IDEs, and application servers frequently require the JAVA_HOME environment variable to locate your Java installation. For comprehensive configuration instructions covering system-wide and per-user setups, see our guide on setting the Java environment path in Ubuntu. This section provides a quick setup for the current user.

To quickly identify the installation path of your currently active Java version, use this command:

dirname $(dirname $(readlink -f $(which java)))

With OpenJDK 21 active on a 64-bit system, the command returns:

/usr/lib/jvm/java-21-openjdk-amd64

On ARM64 systems (such as Raspberry Pi or AWS Graviton), the path is /usr/lib/jvm/java-21-openjdk-arm64 instead. Always use the dirname command above to detect the correct path for your architecture.

To set this as your JAVA_HOME for the current user, add the following to your ~/.bashrc file:

echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64' >> ~/.bashrc
source ~/.bashrc

After reloading the configuration, verify the variable is configured correctly:

echo $JAVA_HOME
/usr/lib/jvm/java-21-openjdk-amd64

Test the Installation with a Sample Program

Verifying your installation goes beyond checking version numbers. To confirm the full toolchain works correctly, compile and run a test program that demonstrates Java 21’s new features in action.

Create a Test Program

First, create a new Java source file using any text editor:

nano Hello.java

Next, add the following code, which uses Java 21’s record pattern matching feature to demonstrate the installation is fully functional:

record SystemInfo(String javaVersion, String osName) {}

public class Hello {
    public static void main(String[] args) {
        var info = new SystemInfo(
            System.getProperty("java.version"),
            System.getProperty("os.name")
        );
        
        if (info instanceof SystemInfo(String version, String os)) {
            System.out.println("Hello from OpenJDK 21!");
            System.out.println("Running Java " + version + " on " + os);
        }
    }
}

Save the file by pressing Ctrl+O, then exit nano with Ctrl+X.

Compile and Run the Program

Next, compile the source file into Java bytecode:

javac Hello.java

Successful compilation produces no output and creates a Hello.class file in the current directory. If the compilation fails, verify that OpenJDK 21 is the active version using javac --version.

Once compilation succeeds, execute the compiled program:

java Hello

Expected output:

Hello from OpenJDK 21!
Running Java 21.0.x on Linux

This output confirms your OpenJDK 21 installation compiles and executes Java code correctly, including modern language features like records and pattern matching.

Troubleshoot Common Issues

This section addresses problems you may encounter when installing or using OpenJDK 21 on Ubuntu.

Package Not Found on Ubuntu 22.04

If apt install openjdk-21-jdk fails with “Unable to locate package” on Ubuntu 22.04, the universe repository may be disabled. This can occur on minimal installations or customized systems. To diagnose this, check if universe is enabled:

grep -r "universe" /etc/apt/sources.list /etc/apt/sources.list.d/

On a standard installation, you should see multiple lines containing “universe”:

deb http://archive.ubuntu.com/ubuntu/ jammy universe
deb http://archive.ubuntu.com/ubuntu/ jammy-updates universe
deb http://security.ubuntu.com/ubuntu/ jammy-security universe

If you see no output or only commented lines (starting with #), then enable the universe repository:

sudo add-apt-repository universe
sudo apt update

After enabling universe, retry the installation command. This step is unnecessary on Ubuntu 24.04 and later, where OpenJDK 21 is in the main repository.

Wrong Java Version Active

If java --version reports a different version than expected after installation, multiple Java versions exist on your system with a higher priority assigned to another version. Therefore, to fix this, list available alternatives:

sudo update-alternatives --config java

Select the entry corresponding to OpenJDK 21 and confirm your selection. Also update the compiler using update-alternatives --config javac to maintain consistency between runtime and compiler.

JAVA_HOME Not Recognized

Build tools failing with “JAVA_HOME is not defined” or pointing to an incorrect path indicates the environment variable needs configuration. First, identify the correct path:

dirname $(dirname $(readlink -f $(which java)))

Once you identify the correct path, add the export statement to your shell configuration file:

echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64' >> ~/.bashrc
source ~/.bashrc

Verify the variable is set by running echo $JAVA_HOME. The path should match your OpenJDK 21 installation directory.

Bytecode Version Mismatch Errors

Errors mentioning “unsupported major.minor version” or “class file version X.Y” occur when code compiled with a newer Java version runs on an older JRE. Therefore, to resolve this, verify your compiler and runtime versions match:

java --version
javac --version

Both commands should show Java 21. If they differ, align them using update-alternatives for both java and javac.

Remove OpenJDK 21

If you no longer need OpenJDK 21, use the appropriate removal command based on which installation method you used.

Remove Ubuntu APT OpenJDK

To remove the OpenJDK 21 packages installed from Ubuntu’s default repositories:

sudo apt remove openjdk-21-jdk openjdk-21-jre
sudo apt autoremove

Remove Eclipse Temurin

To remove Eclipse Temurin 21 installed from the Adoptium repository:

sudo apt remove temurin-21-jdk
sudo apt autoremove

In addition, optionally remove the Adoptium repository and GPG key if you no longer need any Temurin packages:

sudo rm /etc/apt/sources.list.d/adoptium.sources
sudo rm /usr/share/keyrings/adoptium.gpg
sudo apt update

Verify Removal

After removal, verify by checking for remaining Java installations:

java --version

If no other Java versions are installed, this command returns “command not found.” Alternatively, if other versions remain, the output shows which Java version is now active.

If you configured JAVA_HOME in your ~/.bashrc file, remember to update or remove that export line after uninstalling OpenJDK 21. Applications relying on JAVA_HOME will fail if the path points to a removed installation.

Conclusion

You have installed OpenJDK 21 on Ubuntu and verified the installation works correctly. The update-alternatives system provides clean version switching when multiple Java installations coexist, and the JAVA_HOME configuration enables compatibility with build tools and application servers. For Java development workflows, consider installing Apache Maven to manage project dependencies and builds. If your stack requires an earlier LTS release, explore OpenJDK 17 for broad framework compatibility. For the latest stable LTS features including finalized scoped values, explore OpenJDK 25.

Useful Resources

For additional Java documentation and alternative distributions, these resources provide authoritative information:

Leave a Comment

Let us know you are human: