BLOG POSTS
How to Install Java on CentOS and Fedora

How to Install Java on CentOS and Fedora

If you’re setting up a CentOS or Fedora server and need Java running smoothly, you’ve come to the right place. Whether you’re deploying web applications, running microservices, or setting up enterprise software like Elasticsearch or Jenkins, Java is probably going to be your bread and butter. This guide will walk you through multiple installation methods, from package managers to manual installations, plus some pro tips that’ll save you headaches down the road. We’ll cover OpenJDK, Oracle JDK, version management, and even throw in some automation scripts because who doesn’t love efficiency?

How Java Installation Works on RHEL-Based Systems

Before diving into commands, let’s understand what’s happening under the hood. CentOS and Fedora use different package managers (yum/dnf respectively), but both follow similar patterns for Java installation. Here’s the breakdown:

Package Management Hierarchy:
• **DNF/YUM repositories** – Your primary source for OpenJDK packages
• **RPM packages** – Direct installation files you can download
• **SDKMAN** – Third-party version manager (my personal favorite)
• **Manual installation** – Download and extract approach

The key difference? CentOS 7 uses `yum`, CentOS 8+ and Fedora use `dnf`. Both systems maintain multiple Java versions simultaneously using the `alternatives` system – think of it as a symlink manager on steroids.

Java Version Landscape (2024 stats):
• Java 11 LTS: ~48% enterprise adoption
• Java 17 LTS: ~31% adoption (rapidly growing)
• Java 8 LTS: ~18% (legacy systems)
• Java 21 LTS: ~3% (newest LTS, just released)

Quick Setup: The Copy-Paste Solution

Let’s start with the fastest method. Here’s your copy-paste installation for both systems:

For CentOS 7:

# Update system first (always!)
sudo yum update -y

# Install OpenJDK 11 (recommended LTS)
sudo yum install -y java-11-openjdk java-11-openjdk-devel

# Set JAVA_HOME permanently
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk' | sudo tee -a /etc/environment
source /etc/environment

# Verify installation
java -version
javac -version

For CentOS 8+ and Fedora:

# Update system
sudo dnf update -y

# Install OpenJDK 11
sudo dnf install -y java-11-openjdk java-11-openjdk-devel

# Set JAVA_HOME
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk' | sudo tee -a /etc/environment
source /etc/environment

# Verify
java -version
javac -version

**Pro tip:** Always install the `-devel` package unless you’re running a production server that only executes Java apps. The devel package includes `javac` compiler and other development tools.

Step-by-Step Installation Methods

Method 1: Repository Installation (Recommended)

First, let’s see what Java versions are available:

# CentOS 7
yum search openjdk

# CentOS 8+/Fedora
dnf search openjdk

You’ll typically see options like:
• `java-8-openjdk` – Java 8 LTS
• `java-11-openjdk` – Java 11 LTS (recommended)
• `java-17-openjdk` – Java 17 LTS
• `java-21-openjdk` – Java 21 LTS (latest)

Install your chosen version:

# Example: Installing Java 17
sudo dnf install -y java-17-openjdk java-17-openjdk-devel

# Check installed location
ls -la /usr/lib/jvm/

Method 2: Managing Multiple Java Versions

Here’s where it gets interesting. You can install multiple Java versions and switch between them:

# Install multiple versions
sudo dnf install -y java-11-openjdk java-17-openjdk java-21-openjdk

# Check alternatives
sudo alternatives --config java

# You'll see something like:
# 1    /usr/lib/jvm/java-11-openjdk/bin/java
# 2    /usr/lib/jvm/java-17-openjdk/bin/java
# 3    /usr/lib/jvm/java-21-openjdk/bin/java

# Set default for javac too
sudo alternatives --config javac

Method 3: SDKMAN (The Power User Approach)

SDKMAN is a game-changer for developers managing multiple Java versions. Here’s the setup:

# Install SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# List available Java versions
sdk list java

# Install specific versions
sdk install java 11.0.21-tem    # Temurin (Eclipse Foundation)
sdk install java 17.0.9-tem     # Temurin Java 17
sdk install java 21.0.1-oracle  # Oracle JDK 21

# Switch between versions
sdk use java 17.0.9-tem
sdk default java 11.0.21-tem

Method 4: Oracle JDK Manual Installation

Sometimes you need the official Oracle JDK. Here’s how:

# Download Oracle JDK (replace URL with current version)
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_rpm.rpm

# Install the RPM
sudo rpm -ivh jdk-21_linux-x64_rpm.rpm

# Set alternatives
sudo alternatives --install /usr/bin/java java /usr/java/latest/bin/java 1
sudo alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 1

Real-World Use Cases and Examples

Scenario 1: Web Application Server Setup

Let’s say you’re setting up a Spring Boot application server:

# Install Java 17 (recommended for Spring Boot 3.x)
sudo dnf install -y java-17-openjdk

# Create service user
sudo useradd -r -s /bin/false webapp

# Set up application directory
sudo mkdir -p /opt/webapp
sudo chown webapp:webapp /opt/webapp

# Create systemd service file
sudo tee /etc/systemd/system/webapp.service > /dev/null <

Scenario 2: Elasticsearch Installation

Elasticsearch has specific Java requirements:

# Elasticsearch 8.x requires Java 11+
sudo dnf install -y java-11-openjdk

# Import Elasticsearch GPG key
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

# Add repository
sudo tee /etc/yum.repos.d/elasticsearch.repo > /dev/null <

Performance Comparison Table:

| Installation Method | Speed | Version Control | Automation Friendly | Enterprise Ready |
|——————-|——-|—————–|——————-|——————|
| DNF/YUM Repository | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| SDKMAN | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| Manual RPM | ⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Oracle Official | ⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |

Troubleshooting Common Issues

Problem: JAVA_HOME not set correctly

# Find Java installation path
readlink -f $(which java)

# Set JAVA_HOME properly (add to ~/.bashrc or /etc/environment)
export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")

# For OpenJDK installations, use:
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

Problem: Multiple Java versions causing conflicts

# Clean up alternatives
sudo alternatives --remove-all java
sudo alternatives --remove-all javac

# Reinstall and reconfigure
sudo dnf reinstall java-11-openjdk
sudo alternatives --auto java

Problem: Out of memory errors

# Check available memory
free -h

# Set JVM memory limits (in systemd service or startup script)
java -Xms512m -Xmx2g -jar your-app.jar

Automation and Scripting

Here’s a comprehensive installation script that handles both CentOS and Fedora:

#!/bin/bash

# Java installation script for CentOS/Fedora
# Usage: ./install-java.sh [version]

JAVA_VERSION=${1:-11}
OS_RELEASE=$(cat /etc/os-release | grep "^ID=" | cut -d'=' -f2 | tr -d '"')

install_java() {
    local version=$1
    local pkg_manager=""
    
    # Detect package manager
    if command -v dnf &> /dev/null; then
        pkg_manager="dnf"
    elif command -v yum &> /dev/null; then
        pkg_manager="yum"
    else
        echo "No supported package manager found"
        exit 1
    fi
    
    echo "Installing Java $version using $pkg_manager..."
    
    # Update system
    sudo $pkg_manager update -y
    
    # Install Java
    sudo $pkg_manager install -y java-${version}-openjdk java-${version}-openjdk-devel
    
    # Set JAVA_HOME
    local java_home="/usr/lib/jvm/java-${version}-openjdk"
    echo "export JAVA_HOME=$java_home" | sudo tee -a /etc/environment
    
    # Create symlink for convenience
    sudo ln -sf $java_home /opt/java
    
    echo "Java $version installation completed!"
    echo "JAVA_HOME set to: $java_home"
    
    # Verify installation
    java -version
}

# Validate Java version
if [[ ! $JAVA_VERSION =~ ^[0-9]+$ ]]; then
    echo "Invalid Java version: $JAVA_VERSION"
    echo "Usage: $0 [8|11|17|21]"
    exit 1
fi

install_java $JAVA_VERSION

Ansible Playbook Example:

---
- name: Install Java on CentOS/Fedora
  hosts: servers
  become: yes
  vars:
    java_version: 11
  
  tasks:
    - name: Install OpenJDK
      package:
        name: 
          - "java-{{ java_version }}-openjdk"
          - "java-{{ java_version }}-openjdk-devel"
        state: present
    
    - name: Set JAVA_HOME
      lineinfile:
        path: /etc/environment
        line: "JAVA_HOME=/usr/lib/jvm/java-{{ java_version }}-openjdk"
        create: yes
    
    - name: Verify Java installation
      command: java -version
      register: java_version_output
    
    - name: Display Java version
      debug:
        msg: "{{ java_version_output.stderr }}"

Advanced Configuration and Optimization

JVM Tuning for Server Environments:

# Create JVM options file
sudo tee /opt/java-opts.conf > /dev/null <

Security Hardening:

# Create restricted Java policy file
sudo tee /etc/java/security/restricted.policy > /dev/null <

Integration with Container Technologies

Modern deployments often involve containers. Here’s a Dockerfile optimized for CentOS-based images:

FROM centos:8

# Install Java 11
RUN dnf update -y && \
    dnf install -y java-11-openjdk-headless && \
    dnf clean all

# Set JAVA_HOME
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk

# Create application user
RUN useradd -r -u 1001 -g root appuser

# Copy application
COPY app.jar /app/
RUN chown appuser:root /app/app.jar

USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:8080/health || exit 1

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

Monitoring and Maintenance

Keep your Java installation healthy with these monitoring scripts:

#!/bin/bash
# Java health check script

echo "=== Java Installation Health Check ==="

# Check Java version
echo "Java Version:"
java -version 2>&1

echo -e "\nJAVA_HOME: $JAVA_HOME"

# Check available alternatives
echo -e "\nAvailable Java alternatives:"
alternatives --display java 2>/dev/null | grep priority || echo "No alternatives configured"

# Check memory usage of Java processes
echo -e "\nJava processes memory usage:"
ps aux | grep java | grep -v grep | awk '{print $2, $4, $11}' | head -10

# Check Java security updates
echo -e "\nChecking for Java updates:"
if command -v dnf &> /dev/null; then
    dnf check-update | grep openjdk || echo "No Java updates available"
else
    yum check-update | grep openjdk || echo "No Java updates available"
fi

Why This Matters for Your Server Infrastructure

Getting Java right on your server setup isn’t just about following commands – it’s about building a foundation that won’t bite you later. Here’s why this approach works:

**Reliability**: Using package managers ensures automatic security updates. In 2023, there were 23 critical Java vulnerabilities patched – you want those updates automated.

**Scalability**: The alternatives system lets you test new Java versions without breaking existing applications. I’ve seen too many production outages from hasty Java upgrades.

**Performance**: Proper JVM tuning can improve application performance by 30-40%. Those memory and GC settings aren’t just suggestions.

**Security**: Java runs with significant privileges. Proper installation and configuration prevent common attack vectors.

If you’re serious about hosting Java applications, consider a VPS solution for development and testing, then scale to a dedicated server for production workloads.

**My recommendations:**
• Use OpenJDK 11 or 17 for new projects (LTS versions)
• Always install the `-devel` package during development
• Set up SDKMAN for developer machines
• Use package managers for production servers
• Automate everything with scripts or Ansible
• Monitor Java processes and memory usage regularly

The Java ecosystem moves fast, but with this foundation, you’ll be ready for whatever comes next. Whether you’re running microservices, big data applications, or enterprise software, you now have the tools to install and manage Java like a pro.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked