Last Updated:

Complete Guide to Liberica JDK 21 Download, Installation and Usage

Java 21, released in September 2023, is the latest Long-Term Support (LTS) release of the Java platform, bringing game-changing features like virtual threads, pattern matching for switch, structured concurrency previews, and performance improvements that make it ideal for modern cloud, microservices, desktop, and embedded workloads. While there are multiple OpenJDK distributions available, Liberica JDK from BellSoft stands out as a fully Java SE TCK-compliant, 100% open-source distribution with cross-platform support (including rare architectures like RISC-V, ARMv7, and PPC), extended LTS support until 2031, and optimized variants for every use case. This guide provides an end-to-end walkthrough of downloading, installing, verifying, and using Liberica JDK 21, including OS-specific installation steps, best practices, common pitfalls to avoid, and practical examples of using JDK 21 features with Liberica.


Table of Contents#

  1. What is Liberica JDK 21?
  2. Pre-Download Requirements & Variant Selection
  3. Step-by-Step Download & Installation Guides 3.1 Windows 3.2 macOS 3.3 Linux 3.4 Container Environments
  4. Post-Install Verification
  5. Common Pitfalls & Best Practices
  6. Example Usage of JDK 21 Features with Liberica
  7. Troubleshooting Common Issues
  8. References

What is Liberica JDK 21?#

Liberica JDK 21 is BellSoft's build of OpenJDK 21 LTS, with the following core value propositions:

  • 100% compliance with the Java SE TCK, guaranteeing compatibility with all standard Java applications
  • Extended LTS support (free public updates until 2027, paid commercial support until 2031)
  • Support for 30+ architectures and operating systems, including embedded and legacy platforms
  • No proprietary code, licensed under GPLv2 with Classpath Exception (free for personal and commercial use with no royalties or usage restrictions)
  • Includes additional optimizations for memory usage and throughput compared to vanilla OpenJDK builds

Key JDK 21 features available out of the box in Liberica JDK 21:

  • Virtual threads (lightweight concurrency model for high-throughput applications)
  • Pattern matching for switch (simplified type checking and conditional logic)
  • Sequenced Collections (standardized API for ordered collections like Lists and SortedMaps)
  • Preview features: Structured Concurrency, Scoped Values, Virtual Thread Locals
  • Security enhancements: TLS 1.3 improvements, SHA-3 support, and enhanced sandbox restrictions

Pre-Download Requirements & Variant Selection#

System Requirements#

OSMinimum SpecsSupported Architectures
Windows 10/11, Server 2016+2GB RAM, 500MB disk spacex64, ARM64
macOS 11 (Big Sur)+2GB RAM, 500MB disk spacex64, Apple Silicon (AArch64)
Linux (Kernel 3.10+)1GB RAM, 300MB disk spacex64, AArch64, ARMv7, PPC, RISC-V
Alpine Linux512MB RAM, 200MB disk spacex64, AArch64

Variant Selection#

Liberica JDK 21 is available in 3 optimized variants to match your use case:

VariantUse CaseFootprintIncluded Components
StandardServer, microservices, cloud workloads, CI/CD agents~300MBFull Java SE runtime, compiler, core tools, JFR
LiteEmbedded systems, IoT, resource-constrained edge devices~120MBStripped core runtime, no unused modules, minimal tooling
FullDesktop applications, developer workstations, JavaFX apps~400MBStandard variant + JavaFX, Mission Control, all optional Java modules

Step-by-Step Download & Installation Guides#

All official Liberica JDK 21 downloads are available on the BellSoft official download page.

Windows Installation#

  1. Navigate to the download page, select Windows as your OS, your system architecture, and MSI as the package type for your chosen variant
  2. Run the downloaded MSI installer
  3. On the custom setup screen, enable the following optional features for ease of use:
    • Add Liberica JDK to PATH
    • Set JAVA_HOME environment variable
    • Associate .jar files with Liberica JDK
  4. Select your install location (default: C:\Program Files\BellSoft\LibericaJDK-21\)
  5. Complete the installation and restart your terminal to apply PATH changes

Option 2: Portable ZIP Archive#

  1. Download the ZIP archive for your architecture and variant
  2. Extract the archive to your preferred location (e.g. C:\Tools\LibericaJDK-21\)
  3. Set the JAVA_HOME system environment variable to the extracted folder path
  4. Add %JAVA_HOME%\bin to the system PATH variable

macOS Installation#

  1. Add the BellSoft tap to Homebrew:
    brew tap bell-sw/liberica
  2. Install your preferred variant:
    # Standard variant
    brew install liberica-jdk21
    # Full variant (with JavaFX)
    brew install liberica-jdk21-full
    # Lite variant
    brew install liberica-jdk21-lite
  3. Homebrew automatically configures PATH and JAVA_HOME for you

Option 2: DMG Installer#

  1. Download the DMG file for your architecture (x64 or AArch64 for Apple Silicon) from the official download page
  2. Open the DMG and run the .pkg installer inside to install Liberica JDK
  3. After installation, add the following line to your ~/.zshrc or ~/.bash_profile to set JAVA_HOME:
    export JAVA_HOME=$(/usr/libexec/java_home -v 21)
  4. Restart your terminal to apply changes

Linux Installation#

Debian/Ubuntu (APT Repository)#

  1. Import the BellSoft GPG signing key:
    wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | sudo apt-key add -
  2. Add the BellSoft APT repository:
    echo "deb [arch=amd64] https://apt.bell-sw.com/ stable main" | sudo tee /etc/apt/sources.list.d/bellsoft.list
  3. Update package lists and install Liberica JDK 21:
    sudo apt update
    # Install standard variant
    sudo apt install bellsoft-java21
    # Install full variant: sudo apt install bellsoft-java21-full
    # Install lite variant: sudo apt install bellsoft-java21-lite

RHEL/CentOS/Fedora (DNF Repository)#

  1. Import the GPG key:
    sudo rpm --import https://download.bell-sw.com/pki/GPG-KEY-bellsoft
  2. Create the BellSoft repo file:
    sudo tee /etc/yum.repos.d/bellsoft.repo << EOF
    [BellSoft]
    name=BellSoft Repository
    baseurl=https://yum.bell-sw.com/
    enabled=1
    gpgcheck=1
    gpgkey=https://download.bell-sw.com/pki/GPG-KEY-bellsoft
    EOF
  3. Install Liberica JDK 21:
    sudo dnf install bellsoft-java21

Alpine Linux#

  1. Add the BellSoft APK repository:
    echo "https://apk.bell-sw.com/main" | sudo tee -a /etc/apk/repositories
    sudo wget -P /etc/apk/keys/ https://apk.bell-sw.com/[email protected]
  2. Install Liberica JDK 21:
    sudo apk add bellsoft-java21

Container Environments#

Official Liberica JDK 21 container images are hosted on Docker Hub, optimized for small size and security.

Example Multi-Stage Dockerfile#

# Build stage with full JDK
FROM bellsoft/liberica-openjdk-debian:21 AS builder
WORKDIR /app
COPY . .
RUN javac Main.java
 
# Runtime stage with minimal JRE
FROM bellsoft/liberica-openjre-alpine:21
WORKDIR /app
COPY --from=builder /app/Main.class .
CMD ["java", "Main"]

This produces a runtime image of ~100MB, 70% smaller than standard OpenJDK images.


Post-Install Verification#

  1. Verify the Java runtime version:
    java -version
    Expected output:
    openjdk version "21.0.3" 2024-04-16 LTS
    OpenJDK Runtime Environment (build 21.0.3+9-LTS)
    OpenJDK 64-Bit Server VM (build 21.0.3+9-LTS, mixed mode, sharing)
    
  2. Verify the Java compiler:
    javac -version
    Expected output: javac 21.0.3
  3. Verify GPG signature (optional, for production deployments): Download the .sig file alongside your installation package, then run:
    gpg --verify liberica-jdk-21.0.3.tar.gz.sig liberica-jdk-21.0.3.tar.gz
    The output should confirm a valid signature from BellSoft.

Common Pitfalls & Best Practices#

Common Pitfalls to Avoid#

  1. Downloading the wrong architecture: Using x64 builds on Apple Silicon or ARM64 systems will work via emulation but cause significant performance losses
  2. Downloading JRE instead of JDK for development: JRE packages do not include the javac compiler or development tools
  3. Missing JAVA_HOME configuration: Build tools like Maven, Gradle, and Spring Boot rely on JAVA_HOME to detect the correct Java runtime
  4. Using the wrong variant for production: Using the Full variant for server workloads adds unnecessary bloat and increases attack surface

Best Practices#

  1. Use package managers for installation: Package managers handle automatic updates, permission configuration, and PATH setup automatically
  2. Pin versions in production: Avoid using latest tags for container images or package installs; pin to specific minor versions (e.g. 21.0.3) to avoid unexpected breaking changes
  3. Use Lite variant for edge/embedded deployments: The Lite variant reduces memory footprint by 60% compared to standard builds
  4. Enable auto-updates for development environments: Receive regular security patches and bug fixes without manual intervention
  5. Use consistent JDK variants across environments: Use the same Liberica JDK variant in development, testing, and production to eliminate compatibility issues
  6. Use Liberica Native Image Kit (NIK) for native binaries: BellSoft's GraalVM-based NIK is optimized for Liberica JDK 21, producing smaller, faster native executables for cloud and serverless workloads

Example Usage of JDK 21 Features with Liberica#

1. Virtual Threads (Standard Feature)#

public class VirtualThreadTest {
    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();
        // Create 10,000 virtual threads (impossible with platform threads due to memory limits)
        Thread[] threads = new Thread[10000];
        for (int i = 0; i < 10000; i++) {
            threads[i] = Thread.ofVirtual().start(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        for (Thread t : threads) t.join();
        System.out.printf("Ran 10,000 virtual threads in %dms%n", System.currentTimeMillis() - start);
    }
}

Compile and run:

javac VirtualThreadTest.java
java VirtualThreadTest

2. Pattern Matching for Switch (Standard Feature)#

public class SwitchPatternTest {
    public static String format(Object input) {
        return switch (input) {
            case Integer i -> String.format("Integer value: %d", i);
            case String s -> String.format("String value: %s", s);
            case Double d when d > 0 -> String.format("Positive double: %.2f", d);
            case null -> "Null input";
            default -> String.format("Unknown type: %s", input.getClass().getName());
        };
    }
 
    public static void main(String[] args) {
        System.out.println(format(42));
        System.out.println(format("Liberica JDK 21"));
        System.out.println(format(3.14));
    }
}

3. Structured Concurrency (Preview Feature)#

Compile with preview flags enabled:

javac --enable-preview --release 21 StructuredConcurrencyTest.java
java --enable-preview StructuredConcurrencyTest

Code:

import java.util.concurrent.StructuredTaskScope;
import java.util.concurrent.ExecutionException;
 
public class StructuredConcurrencyTest {
    record APIResponse(String userData, String orderData) {}
 
    public static APIResponse fetchData() throws InterruptedException, ExecutionException {
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            // Fork parallel tasks
            var userTask = scope.fork(() -> "User data fetched from API");
            var orderTask = scope.fork(() -> "Order data fetched from API");
            
            scope.join();
            scope.throwIfFailed(); // Fail fast if any task fails
 
            return new APIResponse(userTask.get(), orderTask.get());
        }
    }
 
    public static void main(String[] args) throws Exception {
        System.out.println(fetchData());
    }
}

Troubleshooting Common Issues#

  1. PATH Conflicts: If multiple JDKs are installed, run where java (Windows) or which java (Linux/macOS) to check which runtime is being used, and adjust the PATH order to prioritize Liberica JDK
  2. Permission Errors on Linux: Run sudo chmod -R +x $JAVA_HOME/bin to fix execute permission errors
  3. Architecture Mismatch Errors: If you get "This app cannot run on your PC" on Windows, confirm you downloaded the correct build for your x64/ARM64 architecture
  4. Missing Library Errors on Alpine: Ensure you downloaded the Alpine-specific Liberica build (compiled for musl libc) instead of the standard Linux build (compiled for glibc)

References#

  1. Official BellSoft Liberica JDK 21 Download Page
  2. Liberica JDK 21 Release Notes
  3. OpenJDK 21 Official Documentation
  4. Liberica JDK Licensing Information
  5. Liberica Container Image Documentation