Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to install Java 17 and 21 on Red Hat Enterprise Linux 8

December 10, 2018
Severin Gehwolf
Related topics:
JavaLinuxProgramming languages & frameworks
Related products:
Red Hat Enterprise Linux

Share:

    In this article, you’ll learn how to install and run simple Java applications on Red Hat Enterprise Linux (RHEL) 8, how to switch between two parallel installed major JDK versions via alternatives, and how to select one of the two JDKs on a per-application basis.

    Four major versions of Java are supported in RHEL 8: Java 21, 17, 11, and Java 8. In this article, I’ll refer to Java 21 as JDK (Java Development Kit) 21 since we are focusing on the development aspect of using Java. JDK 21 refers to Red Hat build of OpenJDK 21. The same applies to other JDK versions.

    TL;DR: Install Java on RHEL

    To install JDK 21 on RHEL 8, use:

    $ sudo yum install java-21-openjdk-devel

    (If you didn't, select Make this user administrator during install; see this article on how to enable sudo on RHEL).

    Then, run Java "Hello World" as follows:

    $ cat > HelloWorld.java <<HELLO
    public class HelloWorld {
      public static void main(String[] args) {
        System.out.println("Hello World!");
      }
    }
    HELLO
    $ javac HelloWorld.java && java HelloWorld
    Hello World!

    To install JDK 17 on RHEL 8, use:

    $ sudo yum install java-17-openjdk-devel

    Then, run Java “Hello World” as follows:

    $ cat > HelloWorld.java <<HELLO
    public class HelloWorld {
      public static void main(String[] args) {
        System.out.println("Hello World!");
      }
    }
    HELLO
    $ /usr/lib/jvm/java-17-openjdk/bin/java HelloWorld.java
    Hello World!

    Yes, with JDK 11 and above, you can directly run Java source files. The compilation step is handled for you.

    Video demo

    If you prefer to watch a short 4-minute demo video, here it is:

    The longer version

    Let's consider we have a freshly commissioned Red Hat Enterprise Linux 8 machine and we'd like to use it for running Java applications.

    How to find available Java packages

    In order to figure out which RPM packages to install, we can ask the packaging system which ones provide the java binary:

    $ yum provides \*/bin/java
    

    This command tells us that packages java-21-openjdk-headless, java-17-openjdk-headless, java-11-openjdk-headless and java-1.8.0-openjdk-headless all provide the java binary. For the purpose of this article, we’re interested in the development kits, so we’ll install the -devel sub-packages instead. The -devel packages will pull in -headless packages as a dependency. If you already know that RHEL packages are OpenJDK builds, yum list available might be useful, too:

    $ yum list available \*openjdk\*
    

    For the purpose of this article, we are going to install JDK 21 and JDK 17 in parallel, and also install Maven:

    $ sudo yum install java-21-openjdk-devel java-17-openjdk-devel maven
    

    Switch Java versions

    In the previous step, we installed JDK 21 and JDK 17 in parallel. At this point in time, JDK 8 is the main JDK on RHEL 8. That’s why you get this output when running java -version on a fresh RHEL 8 install even though you didn't install JDK 8 explicitly:

    $ java -version
    openjdk version "1.8.0_422"
    OpenJDK Runtime Environment (build 1.8.0_422-b05)
    OpenJDK 64-Bit Server VM (build 25.422-b05, mixed mode)
    

    There are two ways to select the Java version you want:

    1. Switch java and javac binaries system wide via alternatives. This approach requires root privileges.
    2. Select the JDK on a per-application basis by setting JAVA_HOME.

    Select Java versions with alternatives

    java and javac binaries on RHEL 8 are managed by the alternatives system. This means a system administrator can switch the system java (or javac) to be something other than the default, JDK 8. The alternatives system uses priorities in order to determine which JDK should be available via /usr/bin/java. JDK 8 has been given a higher priority on RHEL 8 than other JDKs. But we are getting ahead of ourselves. First, let's see which binaries are managed by alternatives:

    $ alternatives --list
    

    We see that java and javac are managed by alternatives. Next, we are going to switch to JDK 21, using the alternatives --config command:

    $ sudo alternatives --config java
    There are 3 programs which provide 'java'.
      Selection    Command
    -----------------------------------------------
       1           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.12.0.7-2.el8.x86_64/bin/java)
    *+ 2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.422.b05-2.el8.x86_64/jre/bin/java)
       3           java-21-openjdk.x86_64 (/usr/lib/jvm/java-21-openjdk-21.0.4.0.7-1.el8.x86_64/bin/java)
    Enter to keep the current selection[+], or type selection number: 3
    

    This will switch the system java binary to JDK 21. We do the same for javac since java and javac are independently managed. There is no need to switch anything else as every other JDK binary will switch either with the java or the javac binary:

    $ sudo alternatives --config javac
    There are 3 programs which provide 'javac'.
      Selection    Command
    -----------------------------------------------
       1           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.12.0.7-2.el8.x86_64/bin/javac)
    *+ 2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.422.b05-2.el8.x86_64/bin/javac)
       3           java-21-openjdk.x86_64 (/usr/lib/jvm/java-21-openjdk-21.0.4.0.7-1.el8.x86_64/bin/javac)
    Enter to keep the current selection[+], or type selection number: 3
    

    Switch alternatives non-interactively

    Here is an approach to switch to JDK 21, via alternatives, using non-interactive means, which comes in handy if you need to script it:

    $ JAVA_21=$(alternatives --display java | grep 'family java-21-openjdk' | cut -d' ' -f1)
    $ sudo alternatives --set java $JAVA_21
    

    Similarly, switching to JDK 8 via alternatives by non-interactive means:

    $ JAVA_8=$(alternatives --display java | grep 'family java-1.8.0-openjdk' | cut -d' ' -f1)
    $ sudo alternatives --set java $JAVA_8
    

    A similar approach can be followed for javac.

    Select Java versions by setting JAVA_HOME

    Many applications support using the JAVA_HOME environment variable, as a way to specify which JDK should be used to run the application. The examples below demonstrate this usage when running maven. This approach is handy if you don’t have root privileges, but both JDKs are already installed on your system.

    Selecting JDK 21:

    $ JAVA_HOME=/usr/lib/jvm/java-21-openjdk mvn --version
    Apache Maven 3.5.4 (Red Hat 3.5.4-5)
    Maven home: /usr/share/maven
    Java version: 21.0.4, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-21-openjdk-21.0.4.0.7-1.el8.x86_64
    Default locale: en_US, platform encoding: UTF-8
    OS name: "linux", version: "4.18.0-513.5.1.el8_9.x86_64", arch: "amd64", family: "unix"
    

    Selecting JDK 17:

    $ JAVA_HOME=/usr/lib/jvm/java-17-openjdk mvn --version
    Apache Maven 3.5.4 (Red Hat 3.5.4-5)
    Maven home: /usr/share/maven
    Java version: 17.0.12, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-17-openjdk-17.0.12.0.7-2.el8.x86_64
    Default locale: en_US, platform encoding: UTF-8
    OS name: "linux", version: "4.18.0-513.5.1.el8_9.x86_64", arch: "amd64", family: "unix"

    This feature also comes in handy if you have multiple minor JDK versions installed as Leo Ufimtsev described in his article for RHEL 7.

    Launch single-file source code programs in JDK 11 and later

    With JEP 330, part of JDK 11 and later, it’s possible to run Java code in a script-like fashion. The feature is called Launch Single-File Source-Code Programs, and it lets you use Java as scripting language. Here is a simple example:

    $ cat > factorial <<FACT
    #!/usr/lib/jvm/java-11-openjdk/bin/java --source 8
    public class Factorial {
      private static void usage() {
        System.err.println("factorial <number>");
        System.exit(1);
      }
      private static long factorial(int num) {
        if (num <= 1) {
          return 1;
        }
        if (num == 2) {
          return 2;
        }
        return factorial(num - 1) * num;
      }
      public static void main(String[] args) {
        if (args.length != 1) {
          usage();
        }
        int num = -1;
        try {
          num = Integer.parseInt(args[0]);
        } catch (Exception e) {
          System.err.println("Error: Argument not a number!");
          usage();
        }
        System.out.println(factorial(num));
      }
    }
    FACT
    $ chmod +x factorial
    $ ./factorial 6
    720

    Thank you. I hope you’ve found this article useful.

    Last updated: September 3, 2024

    Related Posts

    • Best practices for Java in single-core containers

    • Java 17: What’s new in OpenJDK's container awareness

    • A faster way to access JDK Flight Recorder data

    • How to use Convert2RHEL to migrate CentOS to RHEL

    • 6 steps to install Ansible Automation Platform 2.3 on RHEL

    • How to build RHEL images for edge deployments

    Recent Posts

    • More Essential AI tutorials for Node.js Developers

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    What’s up next?

    Download Java in a Nutshell, the reference guide every Java developer needs at their fingertips. This book helps you get the most out of versions through Java 17, with examples that show how to take advantage of modern Java APIs and development best practices.

    Download the e-book
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue