SDKMAN ile Çoklu Java Sürümü Yönetimi

Birden fazla Java projesi üzerinde çalışan her geliştirici ya da sistem yöneticisi şu problemle karşılaşmıştır: bir proje Java 8 istiyor, diğeri Java 17, bir diğeri ise Java 21. Sistem genelinde tek bir Java sürümü kurulu olduğunda bu durum ciddi baş ağrısına dönüşür. JAVA_HOME değişkenini her seferinde elle güncellemek, sembolik linkleri yönetmek, farklı JDK paketlerini farklı dizinlere kurup her geçişte ortam değişkenlerini düzenlemek… Tüm bunlar hem zaman kaybettirir hem de hata yapmaya çok açıktır. İşte tam bu noktada SDKMAN devreye giriyor.

SDKMAN Nedir ve Neden Kullanmalısınız

SDKMAN (Software Development Kit Manager), JVM tabanlı diller ve araçlar için geliştirilmiş bir sürüm yönetim aracıdır. Java, Kotlin, Groovy, Scala, Maven, Gradle gibi onlarca SDK’yı kolayca kurmanızı, yönetmenizi ve farklı sürümler arasında geçiş yapmanızı sağlar. Bash üzerine inşa edilmiştir, dolayısıyla Linux ve macOS üzerinde sorunsuz çalışır. Windows için WSL (Windows Subsystem for Linux) kullanılabilir.

SDKMAN’in temel avantajları şöyle sıralanabilir:

  • Çoklu sürüm desteği: Aynı anda onlarca farklı Java sürümünü kurulu tutabilirsiniz.
  • Proje bazlı sürüm sabitleme: .sdkmanrc dosyası sayesinde her projeye özel JDK sürümü tanımlayabilirsiniz.
  • Otomatik ortam yönetimi: JAVA_HOME ve PATH değişkenleri otomatik olarak güncellenir.
  • Geniş dağıtım desteği: Oracle JDK, OpenJDK, GraalVM, Temurin, Zulu, Corretto gibi pek çok JDK dağıtımını destekler.
  • Minimal bağımlılık: Sadece bash, curl, zip ve unzip yeterlidir.

SDKMAN Kurulumu

Kurulum son derece basittir. Terminal açıp şu komutu çalıştırmanız yeterli:

curl -s "https://get.sdkman.io" | bash

Kurulum tamamlandıktan sonra SDKMAN’i mevcut oturuma yüklemek için:

source "$HOME/.sdkman/bin/sdkman-init.sh"

Bu satır aynı zamanda ~/.bashrc ve ~/.zshrc dosyalarına otomatik olarak eklenir, dolayısıyla yeni terminal oturumlarında SDKMAN otomatik olarak aktif olur. Kurulumun başarılı olduğunu doğrulamak için:

sdk version

Çıktı olarak SDKMAN x.y.z gibi bir versiyon numarası görmelisiniz. Eğer sdk komutu bulunamıyorsa shell’i yeniden başlatın ya da source komutunu tekrar çalıştırın.

Kurulum sırasında SDKMAN, ~/.sdkman/ dizinini oluşturur. Bu dizin altında tüm SDK’larınız, konfigürasyonlarınız ve betikler yer alır:

  • ~/.sdkman/bin/: SDKMAN’in ana başlatma betiği
  • ~/.sdkman/candidates/: Kurulu tüm SDK’ların bulunduğu yer
  • ~/.sdkman/etc/config: SDKMAN konfigürasyon dosyası

Mevcut Java Sürümlerini Listeleme

SDKMAN üzerinden kurulabilecek Java sürümlerini görmek için:

sdk list java

Bu komut size oldukça uzun bir liste getirir. Listede her satırda dağıtım adı (Vendor), sürüm numarası, dağıtım türü ve tanımlayıcı (Identifier) yer alır. Kurulu olanlar >>> işaretiyle, aktif olan ise ayrıca işaretlenmiş şekilde gösterilir.

Listeden birkaç örnek tanımlayıcı:

  • 21.0.3-tem: Eclipse Temurin JDK 21
  • 17.0.11-tem: Eclipse Temurin JDK 17
  • 8.0.412-tem: Eclipse Temurin JDK 8
  • 21.0.3-graalce: GraalVM Community Edition 21
  • 17.0.11-amzn: Amazon Corretto 17
  • 21.0.3-oracle: Oracle JDK 21

Sadece belirli bir dağıtıma ait sürümleri filtrelemek için grep kullanabilirsiniz:

sdk list java | grep "tem"

Java Kurulumu

Belirli bir sürümü kurmak için sdk install komutunu kullanırsınız. Tanımlayıcıyı sdk list java çıktısından kopyalayıp yapıştırmanız yeterlidir:

sdk install java 21.0.3-tem

Kurulum sırasında SDKMAN, ilgili JDK’yı indirir, ~/.sdkman/candidates/java/ altına açar ve sizden bu sürümü varsayılan yapmak isteyip istemediğinizi sorar. İlk kurulumda “yes” diyebilirsiniz.

Birden fazla sürüm kuralım:

sdk install java 17.0.11-tem
sdk install java 11.0.23-tem
sdk install java 8.0.412-tem

Her kurulumun ardından sürüm değiştirebilir ya da kurulumu tamamlayıp daha sonra geçiş yapabilirsiniz. Kurulu sürümleri görmek için:

sdk list java | grep "installed|local|>>>"

Ya da daha temiz bir çıktı için:

sdk current java

Bu komut şu anda aktif olan Java sürümünü gösterir.

Sürümler Arası Geçiş

Geçici Geçiş (Sadece Mevcut Terminal Oturumu için)

Bir sürümü sadece açık olan terminal penceresinde kullanmak istiyorsanız:

sdk use java 17.0.11-tem

Bu komut yalnızca mevcut shell oturumunu etkiler. Yeni bir terminal açtığınızda varsayılan sürüme dönülür. Bir CI/CD pipeline’ında ya da test scriptinde belirli bir Java sürümüyle çalışmak istediğinizde bu yöntemi kullanabilirsiniz.

Kalıcı Varsayılan Değiştirme

Sistem genelindeki varsayılan Java sürümünü değiştirmek için:

sdk default java 21.0.3-tem

Bu komuttan sonra yeni açacağınız tüm terminal oturumlarında Java 21 aktif olacaktır. JAVA_HOME ve PATH değişkenleri de buna göre güncellenir.

Güncel durumu doğrulamak için:

java -version
echo $JAVA_HOME

Proje Bazlı Sürüm Yönetimi: .sdkmanrc

SDKMAN’in en güçlü özelliklerinden biri, proje dizinine .sdkmanrc dosyası ekleyerek o projeye özel SDK sürümleri tanımlayabilmektir. Bu özelliği aktif etmek için önce konfigürasyonu düzenlemeniz gerekir:

nano ~/.sdkman/etc/config

Şu satırı bulun ve true yapın:

sdkman_auto_env=true

Artık bir proje dizinine girdiğinizde SDKMAN otomatik olarak o dizindeki .sdkmanrc dosyasını okur ve belirtilen sürüme geçer.

Bir proje dizininde .sdkmanrc dosyası oluşturmak için:

cd /home/kullanici/projeler/eski-proje
sdk env init

Bu komut, şu anda aktif olan Java sürümüyle bir .sdkmanrc dosyası oluşturur. İçeriğini düzenleyebilirsiniz:

cat .sdkmanrc
java=8.0.412-tem
maven=3.9.6

Farklı bir proje için Java 21 gerekiyorsa:

cd /home/kullanici/projeler/yeni-proje
sdk env init
# Sonra .sdkmanrc dosyasını düzenleyin
echo "java=21.0.3-tem" > .sdkmanrc

Artık eski-proje dizinine girdiğinizde Java 8, yeni-proje dizinine girdiğinizde Java 21 otomatik olarak aktif olur. Dizinden çıktığınızda varsayılan sürüme geri dönülür.

.sdkmanrc Olmadan Manuel Geçiş

sdkman_auto_env aktif değilse ya da o anki dizinde .sdkmanrc yoksa, sürümü elle yüklemek için:

sdk env

Bu komut, bulunduğunuz dizindeki .sdkmanrc dosyasını okur ve gerekli sürümlere geçiş yapar.

Gerçek Dünya Senaryosu: Mikroservis Ortamı

Düşünün ki bir mikroservis mimarisinde çalışıyorsunuz. Elimizde şu projeler var:

  • payment-service: Eski bir proje, Java 8 ve Maven 3.6 ile yazılmış
  • user-service: Java 11 ve Gradle 7.x ile geliştirilmiş
  • notification-service: En yeni proje, Java 21 ve Gradle 8.x kullanıyor

Her proje dizinine gidip doğru SDK sürümünün otomatik yüklenmesi için şunları yaparsınız:

# Önce gerekli tüm sürümleri kur
sdk install java 8.0.412-tem
sdk install java 11.0.23-tem
sdk install java 21.0.3-tem
sdk install maven 3.6.3
sdk install gradle 7.6.4
sdk install gradle 8.8

# payment-service için
cd /opt/projeler/payment-service
cat > .sdkmanrc << 'EOF'
java=8.0.412-tem
maven=3.6.3
EOF

# user-service için
cd /opt/projeler/user-service
cat > .sdkmanrc << 'EOF'
java=11.0.23-tem
gradle=7.6.4
EOF

# notification-service için
cd /opt/projeler/notification-service
cat > .sdkmanrc << 'EOF'
java=21.0.3-tem
gradle=8.8
EOF

Artık her proje dizinine geçişte ortam otomatik olarak ayarlanır. Takım üyeleri de aynı .sdkmanrc dosyasını kendi makinelerine alarak aynı ortamı yeniden oluşturabilir.

GraalVM ile Native Image Derleme

SDKMAN, GraalVM kurulumunu da kolaylaştırır. Özellikle native image derleme yapıyorsanız GraalVM’e ihtiyacınız vardır:

sdk install java 21.0.3-graalce
sdk use java 21.0.3-graalce

GraalVM kurulduktan sonra native-image aracını da yükleyin:

gu install native-image

Artık Spring Boot native derleme ya da Quarkus native build gibi işlemler için hazırsınız. GraalVM ile normal JVM arasında geçiş yapmak artık tek satırlık bir iş:

# Native derleme için GraalVM'e geç
sdk use java 21.0.3-graalce
./mvnw -Pnative package

# Sonra normal geliştirme için Temurin'e dön
sdk use java 21.0.3-tem

SDKMAN’i CI/CD Pipeline’larında Kullanma

Jenkins, GitLab CI veya GitHub Actions gibi ortamlarda da SDKMAN kullanılabilir. Özellikle kendi runner’larınız varsa bu çok işe yarar.

Bir shell script ile CI ortamında SDKMAN kullanımı:

#!/bin/bash

# SDKMAN'i yükle (eğer yoksa)
if [ ! -d "$HOME/.sdkman" ]; then
    curl -s "https://get.sdkman.io" | bash
fi

# SDKMAN'i aktif et
export SDKMAN_DIR="$HOME/.sdkman"
source "$HOME/.sdkman/bin/sdkman-init.sh"

# Gerekli Java sürümünü kur ve aktif et
sdk install java 17.0.11-tem || true
sdk use java 17.0.11-tem

# Proje derle
java -version
./mvnw clean package -DskipTests

echo "Build tamamlandi: $(java -version 2>&1 | head -1)"

Bu yaklaşımda || true ifadesi önemlidir; sürüm zaten kuruluysa sdk install hata döndürür ama script durmadan devam etmelidir.

SDKMAN Güncelleme ve Bakım

SDKMAN Kendisini Güncelleme

sdk selfupdate

Bu komut SDKMAN’in kendisini en son sürüme getirir.

Kurulu Bir SDK’yı Güncelleme

Temurin Java 17’nin yeni bir patch sürümü çıktıysa:

sdk upgrade java

Bu komut yükseltilebilecek tüm SDK’ları listeler. Belirli bir SDK için:

sdk upgrade java 17.0.11-tem

Kullanılmayan Sürümleri Temizleme

Zamanla kullanılmayan JDK sürümleri disk alanı kaplar. Temizlemek için:

sdk flush archives
sdk flush temp

flush archives indirilmiş zip dosyalarını temizler. flush temp ise geçici dosyaları siler. Kurulu ama artık kullanılmayan bir sürümü tamamen kaldırmak için:

sdk uninstall java 8.0.412-tem

Kaldırmadan önce o sürüme bağımlı başka proje olmadığından emin olun.

SDKMAN Konfigürasyonu

~/.sdkman/etc/config dosyasındaki önemli ayarlar şunlardır:

  • sdkman_auto_answer=true: Kurulum sorularına otomatik “yes” yanıtlar, CI ortamlarında kullanışlıdır.
  • sdkman_auto_env=true: Dizin değişiminde .sdkmanrc otomatik okunur.
  • sdkman_auto_update=false: Otomatik güncelleme denetimini kapatır, kurumsal ortamlarda tercih edilebilir.
  • sdkman_colour_enable=true: Terminal renkli çıktıyı aktif eder.
  • sdkman_beta_channel=false: Beta kanalını kapatır, sadece stabil sürümler görünür.
  • sdkman_rosetta2_compatible=false: Apple Silicon Mac’lerde Rosetta2 uyumlu sürümler için kullanılır.

Konfigürasyon dosyasını düzenledikten sonra değişikliklerin etkili olması için yeni terminal açın ya da:

source "$HOME/.sdkman/bin/sdkman-init.sh"

Docker ile SDKMAN Kullanımı

Dockerfile içinde SDKMAN kullanmak, build ortamını kodla birlikte sürümlendirmek açısından yararlı olabilir:

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y 
    curl 
    zip 
    unzip 
    bash 
    && rm -rf /var/lib/apt/lists/*

ENV SDKMAN_DIR="/root/.sdkman"
ENV JAVA_VERSION="21.0.3-tem"

RUN curl -s "https://get.sdkman.io" | bash && 
    bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && 
    sdk install java $JAVA_VERSION && 
    sdk default java $JAVA_VERSION"

ENV JAVA_HOME="$SDKMAN_DIR/candidates/java/current"
ENV PATH="$JAVA_HOME/bin:$PATH"

WORKDIR /app
COPY . .
RUN bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && ./mvnw clean package"

Bu yaklaşım özellikle geliştirme ve test Dockerfile’larında işe yarar. Production image’leri için multi-stage build ve resmi temel imajları tercih etmek daha uygundur.

Sık Karşılaşılan Sorunlar ve Çözümleri

sdk komutu bulunamıyor hatası: Shell init dosyanıza (.bashrc veya .zshrc) SDKMAN kaynak satırının eklenip eklenmediğini kontrol edin. tail -5 ~/.bashrc ile son satırları görün.

Sürüm kurulumu ağdan dolayı başarısız oluyorsa: Proxy ayarlarınızı kontrol edin. Kurumsal ağlarda şu şekilde proxy tanımlayabilirsiniz:

export http_proxy=http://proxy.sirket.com:3128
export https_proxy=http://proxy.sirket.com:3128
sdk install java 21.0.3-tem

Yerel kurulu bir JDK’yı SDKMAN’e tanıtma: Kendi derlediğiniz ya da özel bir dizine kurduğunuz JDK’yı SDKMAN altına almak için:

sdk install java local-jdk /opt/custom-jdk/jdk-17

Bu komut /opt/custom-jdk/jdk-17 dizinindeki JDK’yı local-jdk tanımlayıcısıyla SDKMAN’e ekler.

zip/unzip yok hatası: Ubuntu/Debian sistemlerde:

sudo apt-get install zip unzip

CentOS/RHEL sistemlerde:

sudo yum install zip unzip

Sonuç

SDKMAN, Java ekosisteminde çalışan her geliştirici ve sistem yöneticisi için neredeyse vazgeçilmez bir araç haline geldi. Kurulumu beş dakika almaz, öğrenme eğrisi minimumdur ve getirdiği kolaylık ciddi zaman tasarrufu sağlar. Özellikle .sdkmanrc ile proje bazlı sürüm sabitleme özelliği, takım içinde ortam tutarlılığını sağlamak açısından büyük değer taşır. “Bende çalışıyor” problemlerinin önemli bir kısmı, farklı Java sürümlerinden kaynaklanır ve bu araç tam olarak o sorunu ortadan kaldırır.

Bugün tek bir Java sürümüyle çalışıyor olsanız bile SDKMAN kurmaya değer. Yarın yeni bir projeye geçiş yaptığınızda ya da mevcut projeniz için farklı bir JDK dağıtımını test etmek istediğinizde elimizde böyle bir araç olması hem konfigürasyonu hem de geri dönüşü son derece kolaylaştırır. Maven ve Gradle gibi araçları da yönetiyor olması ise işi daha da pratik hale getiriyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir