Ubuntu ve Debian’a Java 21 LTS Kurulumu
Java dünyasına adım atmak isteyenler ya da mevcut kurulumlarını güncellemek isteyenler için Ubuntu ve Debian üzerinde Java 21 LTS kurulumu oldukça kritik bir konu. Java 21, September 2023’te yayınlanan ve uzun süreli destek (LTS) alacak olan bu sürüm, sanal iş parçacıkları (Virtual Threads), pattern matching gibi önemli özelliklerle birlikte geliyor. Üretim ortamlarında kararlılık arayan ekipler için bu sürüm ciddi anlamda güçlü bir tercih. Bu yazıda, farklı kurulum yöntemlerini ele alacağız, hangisini ne zaman kullanmanız gerektiğini açıklayacağız ve gerçek dünya senaryolarıyla kurulum sonrası yapılandırmayı da işleyeceğiz.
Java 21 Neden LTS ve Neden Önemli
Java sürümleri her altı ayda bir çıkıyor ancak LTS sürümleri daha uzun süre kurumsal destek alıyor. Java 21, Oracle tarafından 2030’a kadar genişletilmiş destek alacak şekilde planlanmış. Önceki LTS olan Java 17’den Java 21’e geçişte öne çıkan başlıca özellikler şunlar:
- Virtual Threads (JEP 444): Binlerce eş zamanlı işlemi çok daha düşük kaynak kullanımıyla yönetebiliyorsunuz
- Sequenced Collections (JEP 431): Koleksiyon API’sine sıralı erişim için yeni arayüzler eklendi
- Pattern Matching for switch (JEP 441): Switch ifadelerinde tip eşleştirme artık kararlı hale geldi
- String Templates (Preview): Daha okunabilir string birleştirme yaklaşımı
- Generational ZGC: Düşük gecikmeli çöp toplayıcı daha da geliştirildi
Üretim ortamında bir Spring Boot uygulaması, Kafka tüketicisi ya da mikro servis yığını çalıştırıyorsanız, Java 21’in Virtual Threads özelliği özellikle I/O yoğun iş yüklerinde neredeyse sıfır ekstra kod değişikliğiyle dramatik performans artışı sağlıyor.
Kuruluma Başlamadan Önce Sistem Kontrolü
Herhangi bir kurulum öncesinde sisteminizin durumunu kontrol etmeniz gerekiyor. Özellikle farklı Java sürümlerinin bir arada yüklü olduğu ortamlarda bu adım oldukça önemli.
# Mevcut Java sürümünü kontrol et
java -version
# JAVA_HOME değişkenini kontrol et
echo $JAVA_HOME
# Yüklü tüm Java paketlerini listele
dpkg -l | grep -i java
# update-alternatives ile mevcut Java kayıtlarını gör
update-alternatives --list java
Sistemde birden fazla Java sürümü yüklüyse ve uygulamalarınız belirli bir sürüme bağımlıysa, kurulum sonrasında doğru sürümü aktif hale getirmeyi unutmayın. Bu konuya yazının ilerleyen bölümünde detaylıca değineceğiz.
Yöntem 1: APT ile OpenJDK 21 Kurulumu
En temiz ve önerilen yöntem, Ubuntu 22.04/24.04 ve Debian 12 için doğrudan APT paket yöneticisi üzerinden kurulum. Ubuntu 24.04 (Noble Numbat) ile birlikte OpenJDK 21 varsayılan depolardan geliyor.
# Paket listelerini güncelle
sudo apt update
# OpenJDK 21 JDK kurulumu (geliştirme araçları dahil)
sudo apt install -y openjdk-21-jdk
# Sadece çalıştırma ortamı yeterliyse JRE kurulumu
sudo apt install -y openjdk-21-jre
# Headless JRE (sunucu ortamları için, GUI bileşenleri olmadan)
sudo apt install -y openjdk-21-jre-headless
Kurulum tamamlandıktan sonra doğrulama:
# Java sürümünü doğrula
java -version
# Javac (derleyici) sürümünü kontrol et
javac -version
# JVM'in tam yolunu bul
which java
readlink -f $(which java)
Çıktı şuna benzer görünmeli:
openjdk version "21.0.x" 2023-09-19
OpenJDK Runtime Environment (build 21.0.x+xx-Ubuntu-xxxx)
OpenJDK 64-Bit Server VM (build 21.0.x+xx-Ubuntu-xxxx, mixed mode, sharing)
Ubuntu 20.04 ve Debian 11 için Ek Adım
Ubuntu 20.04 Focal ve Debian 11 Bullseye varsayılan depolarında OpenJDK 21 bulunmuyor. Bu sistemler için ubuntu-toolchain-r ya da backports deposu kullanabilirsiniz.
# Ubuntu 20.04 için deadsnakes PPA ekleme (Python gibi Java da bu yolla kurulabiliyor)
# Ancak Java için daha güvenilir yol: ubuntu-toolchain-r veya manuel kurulum
# Debian 11 için backports deposunu etkinleştir
echo "deb http://deb.debian.org/debian bullseye-backports main" | sudo tee /etc/apt/sources.list.d/bullseye-backports.list
sudo apt update
# Backports'tan OpenJDK 21 kurulumu
sudo apt install -y -t bullseye-backports openjdk-21-jdk
Yöntem 2: SDKMAN ile Kurulum (Geliştirici Ortamları İçin İdeal)
SDKMAN, Java geliştiricilerinin en sevdiği araçlardan biri. Birden fazla Java sürümünü yan yana yönetebilmenizi, kolayca geçiş yapabilmenizi sağlıyor. Geliştirme makinenizde hem Java 11 hem Java 17 hem de Java 21 çalıştırmanız gerekiyorsa SDKMAN tam size göre.
# SDKMAN kurulumu
curl -s "https://get.sdkman.io" | bash
# Terminali yeniden başlatın veya aşağıdaki komutu çalıştırın
source "$HOME/.sdkman/bin/sdkman-init.sh"
# SDKMAN versiyonunu kontrol et
sdk version
# Mevcut Java sürümlerini listele
sdk list java
# Java 21 OpenJDK kurulumu (temurin dağıtımı)
sdk install java 21.0.3-tem
# GraalVM CE ile Java 21
sdk install java 21.0.3-graalce
# Mevcut shell oturumu için sürüm değiştir
sdk use java 21.0.3-tem
# Varsayılan sürümü kalıcı olarak ayarla
sdk default java 21.0.3-tem
SDKMAN ile birlikte Maven ve Gradle de kurabilirsiniz, bu da geliştirme ortamı kurulumunu tek elden yönetmenizi sağlıyor:
# Maven kurulumu
sdk install maven 3.9.6
# Gradle kurulumu
sdk install gradle 8.6
Yöntem 3: Oracle JDK 21 Manuel Kurulumu
Bazı kurumsal ortamlarda Oracle’ın resmi JDK’sı zorunlu olabiliyor ya da belirli Oracle özellikleri (Flight Recorder, Mission Control gibi) gerekebiliyor. Bu durumda manuel kurulum yapmanız gerekiyor.
# Oracle sitesinden indirdiğiniz .tar.gz dosyasını işleyelim
# Dosyanın adı: jdk-21.0.3_linux-x64_bin.tar.gz
# Hedef dizini oluştur
sudo mkdir -p /usr/lib/jvm
# Arşivi aç
sudo tar -xzf jdk-21.0.3_linux-x64_bin.tar.gz -C /usr/lib/jvm/
# Dizin adını düzenle (isteğe bağlı, yönetimi kolaylaştırır)
sudo mv /usr/lib/jvm/jdk-21.0.3 /usr/lib/jvm/java-21-oracle
# update-alternatives ile sisteme kaydet
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-21-oracle/bin/java 1
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-21-oracle/bin/javac 1
sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/java-21-oracle/bin/jar 1
# Aktif Java sürümünü seç
sudo update-alternatives --config java
Son komut sizi etkileşimli bir menüye götürür, hangi Java sürümünü kullanmak istediğinizi seçebilirsiniz.
JAVA_HOME Ortam Değişkenini Kalıcı Olarak Ayarlama
Pek çok araç, özellikle Maven, Gradle, Tomcat ve Jenkins gibi uygulamalar JAVA_HOME değişkenine ihtiyaç duyuyor. Bu değişkeni doğru ve kalıcı şekilde ayarlamak önemli.
# Java kurulum yolunu bul
update-alternatives --list java
# Örnek çıktı: /usr/lib/jvm/java-21-openjdk-amd64/bin/java
# /etc/environment dosyasına ekle (tüm kullanıcılar için geçerli)
sudo nano /etc/environment
# Dosyaya şu satırı ekleyin veya güncelleyin:
# JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"
# Değişiklikleri hemen uygula
source /etc/environment
# Doğrulama
echo $JAVA_HOME
# Alternatif: Sadece mevcut kullanıcı için .bashrc veya .profile'a ekle
echo 'export JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"' >> ~/.bashrc
echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Sistem genelinde tüm kullanıcıları etkileyen bir yapılandırma istiyorsanız /etc/profile.d/ dizinine ayrı bir dosya oluşturmak daha düzenli bir yaklaşım:
# Sistem geneli JAVA_HOME yapılandırması
sudo bash -c 'cat > /etc/profile.d/java.sh << EOF
export JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"
export PATH="$JAVA_HOME/bin:$PATH"
EOF'
sudo chmod +x /etc/profile.d/java.sh
source /etc/profile.d/java.sh
Birden Fazla Java Sürümünü Yönetme
Gerçek dünya senaryolarında legacy uygulamalar için Java 11 ya da 17, yeni projeler için Java 21 gerekebiliyor. Ubuntu ve Debian’da update-alternatives mekanizması bu durumu zarif şekilde çözüyor.
# Sistemdeki tüm Java sürümlerini listele
update-alternatives --list java
# Etkileşimli sürüm seçici
sudo update-alternatives --config java
# Çıktı şuna benzer:
# Seçim Yol Öncelik Durum
# ------------------------------------------------------------
# * 0 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 1111 otomatik mod
# 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manuel mod
# 2 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 1111 manuel mod
# Sadece javac için de aynı işlemi yap
sudo update-alternatives --config javac
# Belirli bir proje dizini için geçici sürüm değişimi (.bashrc veya .envrc ile)
# direnv kullanıyorsanız proje dizinine .envrc ekleyebilirsiniz:
echo 'export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"' > .envrc
direnv allow
Kurulum Sonrası Doğrulama ve Test
Kurulumun düzgün çalıştığını doğrulamak için basit bir Java programı derleyip çalıştıralım:
# Test dosyası oluştur
cat > HelloJava21.java << 'EOF'
public class HelloJava21 {
public static void main(String[] args) {
System.out.println("Java Sürümü: " + System.getProperty("java.version"));
System.out.println("Java Vendor: " + System.getProperty("java.vendor"));
System.out.println("JAVA_HOME: " + System.getProperty("java.home"));
// Java 21 Virtual Threads testi
Thread virtualThread = Thread.ofVirtual().start(() -> {
System.out.println("Virtual Thread çalışıyor: " + Thread.currentThread().isVirtual());
});
try {
virtualThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
EOF
# Derle
javac HelloJava21.java
# Çalıştır
java HelloJava21
# Temizle
rm HelloJava21.class HelloJava21.java
Eğer Virtual Thread çıktısı true gösteriyorsa Java 21 kurulumunuz başarıyla tamamlanmış demektir.
JVM Performans Parametreleri ve Temel Ayarlar
Üretim ortamlarında JVM’i varsayılan ayarlarla çalıştırmak genellikle yeterli olmuyor. Özellikle heap boyutu ve çöp toplayıcı seçimi kritik:
# JVM'in hangi GC kullandığını öğren
java -XX:+PrintCommandLineFlags -version 2>&1 | grep GC
# Java 21 ile Generational ZGC kullanımı (düşük gecikme gerektiren uygulamalar)
java -XX:+UseZGC -XX:+ZGenerational -Xms512m -Xmx2g -jar uygulama.jar
# G1GC ile başlatma (genel amaçlı, dengeli)
java -XX:+UseG1GC -Xms256m -Xmx1g -XX:MaxGCPauseMillis=200 -jar uygulama.jar
# Mevcut JVM flaglerini ve varsayılan değerlerini görüntüle
java -XX:+PrintFlagsFinal -version 2>&1 | grep -E "HeapSize|GC"
# Docker/container ortamları için önemli: container-aware ayarlar
java -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -jar uygulama.jar
Container ortamlarında UseContainerSupport özellikle önemli çünkü Java 8u192 öncesinde JVM, container’a ayrılan bellek yerine host belleğini görüyor ve heap boyutunu yanlış hesaplıyordu. Java 21’de bu özellik varsayılan olarak açık geliyor.
Systemd Servisi Olarak Java Uygulaması Çalıştırma
Üretim ortamında bir Java uygulamasını systemd servisi olarak ayağa kaldırmak en güvenilir yaklaşım. Örnek bir Spring Boot uygulaması için:
# Uygulama dizini oluştur
sudo mkdir -p /opt/myapp
sudo cp myapp.jar /opt/myapp/
# Servis kullanıcısı oluştur (güvenlik için)
sudo useradd -r -s /bin/false -d /opt/myapp myapp
# Servis dosyası oluştur
sudo bash -c 'cat > /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My Java 21 Application
After=network.target
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64"
ExecStart=/usr/lib/jvm/java-21-openjdk-amd64/bin/java
-XX:+UseZGC
-XX:+ZGenerational
-XX:+UseContainerSupport
-Xms256m
-Xmx1g
-jar /opt/myapp/myapp.jar
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF'
# Servisi etkinleştir ve başlat
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
# Servis durumunu kontrol et
sudo systemctl status myapp
# Logları izle
sudo journalctl -u myapp -f
Sık Karşılaşılan Sorunlar ve Çözümleri
Sorun: java: command not found hatası
Bu genellikle PATH değişkeninin doğru ayarlanmamış olduğunu gösteriyor. which java komutunun çıktısını kontrol edin ve /etc/environment ya da .bashrc dosyasını düzenleyin.
Sorun: JAVA_HOME is not set uyarısı
Maven veya Gradle bu uyarıyı veriyor olabilir. Yukarıdaki JAVA_HOME ayarlama bölümündeki adımları uygulayın ve terminal oturumunu yeniden başlatın.
Sorun: Yanlış Java sürümü kullanılıyor
# Tüm java binary'lerini bul
find /usr -name "java" -type f 2>/dev/null
# Öncelik sırasını kontrol et
update-alternatives --display java
# Önceliği güncelle
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2000
Sorun: UnsupportedClassVersionError hatası
Derlenen class dosyası çalıştırılan JVM’den daha yeni bir sürüm hedefliyor. Derleme ve çalıştırma ortamlarının aynı Java sürümünü kullandığından emin olun.
Sorun: Docker container içinde Java kurulumu
# Dockerfile örneği
FROM ubuntu:22.04
RUN apt-get update &&
apt-get install -y openjdk-21-jre-headless &&
rm -rf /var/lib/apt/lists/*
ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
Güvenlik Güncellemelerini Takip Etme
Java LTS sürümleri için güvenlik yamaları düzenli aralıklarla geliyor. APT ile kurulum yaptıysanız otomatik güvenlik güncellemeleri için unattended-upgrades paketi kullanabilirsiniz:
# Mevcut güvenlik güncellemelerini kontrol et
apt list --upgradable 2>/dev/null | grep java
# Sadece Java paketlerini güncelle
sudo apt update && sudo apt upgrade openjdk-21-jdk -y
# Güncel Java sürümünü doğrula
java -version
Oracle JDK kullanıyorsanız CPU (Critical Patch Update) döngüsünü takip etmek ve manuel olarak güncelleme yapmak zorundasınız. Bu açıdan OpenJDK ve paket yöneticisi üzerinden kurulum, üretim ortamlarında çok daha pratik bir yaklaşım.
Sonuç
Ubuntu ve Debian’da Java 21 LTS kurulumu için en doğru yöntemi seçmek, kullanım senaryonuza bağlı. Üretim sunucuları için APT üzerinden OpenJDK 21 kurulumu en temiz ve yönetimi en kolay seçenek. Geliştirme makinelerinde birden fazla Java sürümüyle çalışıyorsanız SDKMAN hayat kurtarıyor. Kurumsal Oracle lisans zorunluluğu varsa manuel kurulum kaçınılmaz, ancak güvenlik güncellemelerini manuel takip etmeyi unutmamalısınız.
update-alternatives mekanizmasını iyi öğrenmek, birden fazla JVM sürümünün aynı anda bulunduğu ortamlarda büyük kolaylık sağlıyor. JAVA_HOME değişkenini sistem genelinde doğru ayarlamak, Maven ve Gradle gibi build araçlarının sorunsuz çalışması için şart. Container ortamlarında ise UseContainerSupport ve MaxRAMPercentage parametrelerini doğru yapılandırmak, hem bellek verimliliği hem de kararlılık açısından kritik önem taşıyor.
Java 21’in Virtual Threads özelliğini üretim ortamında denemek istiyorsanız, mevcut Spring Boot veya Quarkus projelerinizi Java 21 üzerine taşımak için bu kurulum rehberi size sağlam bir başlangıç noktası sunacak.
