Rocky Linux 10 and AlmaLinux 10 ship OpenJDK 25 and OpenJDK 21 in their default AppStream repository. Both are LTS releases, but JDK 25 is the current one with security patches guaranteed through September 2033. If you’re running Java workloads on RHEL-family systems, this is the version to standardize on.
This guide covers installing OpenJDK 25 and Oracle JDK 25 on Rocky Linux 10 / AlmaLinux 10, managing multiple Java versions with the alternatives system, configuring JAVA_HOME, testing JDK 25 features, and production tuning. All commands were tested on a Rocky Linux 10.1 system with SELinux in enforcing mode.
Verified working: March 2026 on Rocky Linux 10.1 (Red Quartz), kernel 6.12, SELinux enforcing, OpenJDK 25.0.2+10-LTS (Red Hat build), Oracle JDK 25.0.2+10-LTS-69
What’s New in JDK 25
JDK 25 was released September 16, 2025 as the next long-term support version, replacing JDK 21. The latest patch (25.0.2) shipped January 20, 2026. Key production features:
| JEP | Feature | Impact |
|---|---|---|
| 512 | Compact Source Files | Run .java files directly without class boilerplate. void main() {} just works |
| 519 | Compact Object Headers | Object headers shrink from 128 to 64 bits, reducing heap usage |
| 521 | Generational Shenandoah | Low-pause GC now separates young/old generations |
| 506 | Scoped Values | Thread-safe context sharing for virtual threads (replaces ThreadLocal) |
| 513 | Flexible Constructor Bodies | Validation code before super() calls |
| 514 | AOT Ergonomics | Faster startup with -XX:AOTCacheOutput |
| 510 | Key Derivation Function API | Cryptographic key derivation from existing secrets |
| 518 | JFR Cooperative Sampling | Lower overhead profiling |
Full list of 18 JEPs at the OpenJDK 25 project page.
Available Java Versions
Check what the AppStream repository provides:
sudo dnf list available java-*-openjdk-devel
Rocky Linux 10 / AlmaLinux 10 carry two LTS versions:
java-21-openjdk-devel.x86_64 1:21.0.10.0.7-1.el10 appstream
java-25-openjdk-devel.x86_64 1:25.0.2.0.10-4.el10 appstream
Older LTS versions (8, 11, 17) are no longer in the RHEL 10 family repos. If you need them, use the Adoptium Temurin repository.
Install OpenJDK 25
Install the full JDK (compiler, runtime, and development tools):
sudo dnf install -y java-25-openjdk-devel
If you only need to run Java applications (no compiler), install just the JRE:
sudo dnf install -y java-25-openjdk
Verify the installation:
java -version
Red Hat’s build identifies the vendor in the version string:
openjdk version "25.0.2" 2026-01-20 LTS
OpenJDK Runtime Environment (Red_Hat-25.0.2.0.10-3) (build 25.0.2+10-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-25.0.2.0.10-3) (build 25.0.2+10-LTS, mixed mode, sharing)
Confirm the compiler:
javac -version
javac 25.0.2
The JDK installs to /usr/lib/jvm/java-25-openjdk. Check the installed RPM packages:
rpm -qa | grep java-25 | sort
java-25-openjdk-25.0.2.0.10-4.el10.x86_64
java-25-openjdk-crypto-adapter-25.0.2.0.10-4.el10.x86_64
java-25-openjdk-devel-25.0.2.0.10-4.el10.x86_64
java-25-openjdk-headless-25.0.2.0.10-4.el10.x86_64
The crypto-adapter package is specific to Red Hat builds and integrates Java’s cryptography with the system’s FIPS provider.
Install Oracle JDK 25
Oracle provides RPM packages for direct installation. The codebase is identical to OpenJDK, but Oracle’s build uses the HotSpot branding and is licensed under the Oracle NFTC (free for production use until September 2028).
Download the RPM:
wget https://download.oracle.com/java/25/latest/jdk-25_linux-x64_bin.rpm -O /tmp/jdk-25.rpm
Install it:
sudo rpm -ivh /tmp/jdk-25.rpm
Verify Oracle’s build:
/usr/lib/jvm/jdk-25.0.2-oracle-x64/bin/java -version
java version "25.0.2" 2026-01-20 LTS
Java(TM) SE Runtime Environment (build 25.0.2+10-LTS-69)
Java HotSpot(TM) 64-Bit Server VM (build 25.0.2+10-LTS-69, mixed mode, sharing)
Oracle JDK installs to /usr/lib/jvm/jdk-25.0.2-oracle-x64. Note that the Oracle RPM doesn’t register itself with the alternatives system automatically on RHEL-family systems. To make it the default, register it manually:
sudo alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-25.0.2-oracle-x64/bin/java 2
sudo alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-25.0.2-oracle-x64/bin/javac 2
Clean up the downloaded RPM:
rm /tmp/jdk-25.rpm
Set JAVA_HOME
Many Java applications and build tools (Maven, Gradle, Tomcat, WildFly) need JAVA_HOME. Set it system-wide:
echo 'export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))' | sudo tee /etc/profile.d/java.sh
source /etc/profile.d/java.sh
echo $JAVA_HOME
/usr/lib/jvm/java-25-openjdk
This resolves dynamically based on the current default. For systemd service files, use the explicit path:
| JDK Build | JAVA_HOME Path |
|---|---|
| OpenJDK 25 (dnf) | /usr/lib/jvm/java-25-openjdk |
| OpenJDK 21 (dnf) | /usr/lib/jvm/java-21-openjdk |
| Oracle JDK 25 | /usr/lib/jvm/jdk-25.0.2-oracle-x64 |
Note that RHEL-family paths use java-25-openjdk (no -amd64 suffix), unlike Debian/Ubuntu which appends the architecture.
Switch Between Java Versions
Rocky/AlmaLinux uses alternatives (not update-alternatives like Debian) to manage multiple Java installations.
Install OpenJDK 21 alongside 25:
sudo dnf install -y java-21-openjdk-devel
Check registered alternatives:
sudo alternatives --list | grep java
Switch to Java 21:
sudo alternatives --set java /usr/lib/jvm/java-21-openjdk/bin/java
sudo alternatives --set javac /usr/lib/jvm/java-21-openjdk/bin/javac
Confirm the switch:
java -version
openjdk version "21.0.10" 2026-01-20 LTS
OpenJDK Runtime Environment (Red_Hat-21.0.10.0.7-1) (build 21.0.10+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-21.0.10.0.7-1) (build 21.0.10+7-LTS, mixed mode, sharing)
Switch back to JDK 25:
sudo alternatives --set java /usr/lib/jvm/java-25-openjdk/bin/java
sudo alternatives --set javac /usr/lib/jvm/java-25-openjdk/bin/javac
For an interactive menu:
sudo alternatives --config java
Test JDK 25 Features
Compact Source Files (JEP 512)
Write a Java file with just a main() method and run it directly:
cat > /tmp/Greet.java << 'EOF'
void main() {
System.out.println("Compact source on Java " + System.getProperty("java.version"));
System.out.println("OS: " + System.getProperty("os.name") + " " + System.getProperty("os.version"));
System.out.println("Vendor: " + System.getProperty("java.vendor"));
}
EOF
java /tmp/Greet.java
Compact source on Java 25.0.2
OS: Linux 6.12.0-124.8.1.el10_1.x86_64
Vendor: Red Hat, Inc.
No class wrapper, no compilation step, no String[] args. This is a final feature in JDK 25.
Module Import Declarations (JEP 511, Preview)
Import all public types from a module with a single statement:
cat > /tmp/ModTest.java << 'EOF'
import module java.base;
void main() {
var items = List.of("Rocky", "Linux", "10", "JDK", "25");
items.forEach(System.out::println);
}
EOF
java --enable-preview /tmp/ModTest.java
Rocky
Linux
10
JDK
25
JShell and Built-in Web Server
Test the interactive REPL:
echo 'System.out.println("JShell on " + Runtime.version());' | jshell -q
jshell> JShell on 25.0.2+10-LTS
The built-in web server serves the current directory for quick development testing:
jwebserver -p 8080 -b 0.0.0.0
If firewalld is running, open port 8080 to access it from other machines:
sudo firewall-cmd --add-port=8080/tcp
curl http://localhost:8080/
Garbage Collector Configuration
G1 is the default. JDK 25 also ships ZGC and the new Generational Shenandoah (JEP 521):
| Collector | Flag | Use Case |
|---|---|---|
| G1 (default) | -XX:+UseG1GC | Balanced throughput and latency for most workloads |
| ZGC | -XX:+UseZGC | Sub-millisecond pauses, large heaps |
| Shenandoah | -XX:+UseShenandoahGC | Consistent low-pause with generational support (new in JDK 25) |
Verify the active collector:
java -XX:+PrintFlagsFinal -version 2>&1 | grep "Use.*GC " | grep true
bool UseG1GC = true {product} {ergonomic}
RHEL vs Debian: Key Differences
| Item | Rocky/AlmaLinux 10 | Ubuntu 24.04 / Debian 13 |
|---|---|---|
| Package manager | dnf install java-25-openjdk-devel | apt install openjdk-25-jdk |
| JDK package name | java-25-openjdk-devel | openjdk-25-jdk |
| JRE package name | java-25-openjdk | openjdk-25-jre |
| Install path | /usr/lib/jvm/java-25-openjdk | /usr/lib/jvm/java-25-openjdk-amd64 |
| Version tool | alternatives | update-alternatives |
| Vendor string | Red Hat, Inc. | Ubuntu / Debian |
| Crypto adapter | Includes crypto-adapter RPM (FIPS) | Not included |
| SELinux | Enforcing (default) | Not enabled |
| Available LTS versions | 21 and 25 only | 21 and 25 (plus 8, 11, 17 on Ubuntu) |
Production Tips
Pin the JDK in systemd service files. Use the absolute path to prevent version drift when dnf update installs a newer alternative:
Environment="JAVA_HOME=/usr/lib/jvm/java-25-openjdk"
ExecStart=/usr/lib/jvm/java-25-openjdk/bin/java -jar /opt/myapp/app.jar
Set heap limits explicitly. JDK 25 allocates 25% of system RAM by default:
java -Xms512m -Xmx2g -jar app.jar
Use AOT caching (JEP 514) for faster startup:
java -XX:AOTCacheOutput=app.aot -jar app.jar
java -XX:AOTCache=app.aot -jar app.jar
SELinux stays enforcing. OpenJDK works correctly with SELinux in enforcing mode on Rocky/AlmaLinux 10. No booleans or policy changes needed for standard Java applications. If your app writes to non-standard paths, check ausearch -m avc -ts recent for denials.
Security patches come quarterly. Red Hat backports security fixes to the OpenJDK packages. Keep up with sudo dnf update java-25-openjdk*.
For Java installation on other distributions, see our guides for JDK 25 on Ubuntu 24.04/22.04 or JDK 25 on Debian 13/12. To set the default Java version across the system, see our guide on setting the default Java version.