Sunucu Yönetimi & Linux

    Linux'ta Java JDK Kurulumu

    Linux sunucuya OpenJDK kurup sürümler arası geçiş ve JAVA_HOME ayarıyla Java uygulaması çalıştırmanın rehberi.

    12 dk okuma Güncellendi: 10 Temmuz 2026

    Bir Java uygulamasını ilk kez bir Linux sunucuya taşıdığınızda karşılaştığınız tablo çoğu zaman şudur: proje geliştiricinin makinesinde sorunsuz çalışıyordur ama sunucuda java: command not found hatası ya da UnsupportedClassVersionError gibi sürüm uyuşmazlıkları çıkar. Bunun sebebi karmaşık değildir; Linux dağıtımlarının depolarında birden fazla Java sürümü bulunur, hangi sürümün varsayılan olacağı ve JAVA_HOME değişkeninin nereyi gösterdiği doğru ayarlanmadığında uygulama ya hiç başlamaz ya da beklenmedik şekilde davranır. Bu rehber, bir Spring Boot API'sinden bir Minecraft sunucusuna, kurumsal bir Tomcat uygulamasından basit bir .jar aracına kadar her senaryoda işinize yarayacak sağlam bir kurulum temelini adım adım kurmayı amaçlıyor.

    Aşağıda önce JDK ile JRE arasındaki farkı netleştirecek, sonra hem Debian/Ubuntu (apt) hem de RHEL/AlmaLinux/Rocky (dnf) tarafında OpenJDK kurulumunu göstereceğiz. Ardından işin can alıcı noktasına, yani aynı sunucuda birden çok Java sürümünü barındırıp update-alternatives ile aralarında geçiş yapmaya, JAVA_HOME değişkenini kalıcı biçimde tanımlamaya ve son olarak uygulamanızı systemd servisi olarak arka planda 7/24 çalıştırmaya geçeceğiz. Komutları kendi sunucunuzda birebir çalıştırabilecek şekilde gerçekçi tutuyoruz.

    JDK, JRE ve OpenJDK Arasındaki Fark#

    Kuruluma başlamadan önce üç kavramı ayırmak, ilerideki kafa karışıklığını baştan önler. JRE (Java Runtime Environment) yalnızca Java uygulamalarını çalıştırmak için gereken sanal makineyi ve çekirdek kütüphaneleri içerir. JDK (Java Development Kit) ise JRE'nin üstüne javac derleyicisi, jar paketleyici, jshell ve jstack gibi geliştirme ve teşhis araçlarını ekler. Bir sunucuda çoğu zaman derlenmiş bir .jar ya da .war dosyasını çalıştırdığınız için teorik olarak JRE yeterli görünebilir; ancak pratikte JDK kurmanız şiddetle tavsiye edilir. Çünkü canlı bir sunucuda thread dump almak, heap dökümü incelemek ya da bazen kaynaktan küçük bir düzeltme derlemek gerekir ve bu araçların hepsi JDK ile gelir.

    OpenJDK, Java'nın açık kaynaklı ve ücretsiz referans uygulamasıdır. Eskiden Oracle JDK ile lisans farkları önemli bir tartışma konusuydu; bugün production sunucuları için OpenJDK dağıtımları (Adoptium/Temurin, Amazon Corretto, Red Hat build of OpenJDK, dağıtımların kendi paketleri) tamamen yeterli ve lisans açısından güvenlidir. Bu rehber boyunca dağıtımın kendi deposundan gelen OpenJDK paketlerini kullanacağız, çünkü bunlar güvenlik güncellemelerini paket yöneticisiyle otomatik alır.

    Sürüm seçiminde temel kural şudur: mümkünse bir LTS (Long Term Support) sürümü seçin. LTS sürümler yıllarca güvenlik yaması alır ve production için en güvenli tercihtir. Aşağıdaki tablo, bu rehberin yazıldığı dönemde yaygın kullanılan sürümleri özetliyor.

    SürümTürTipik Kullanım
    Java 8LTS (eski)Eski kurumsal uygulamalar, legacy sistemler
    Java 11LTSHâlâ yaygın, birçok framework destekliyor
    Java 17LTSModern Spring Boot 3, güncel projeler için standart
    Java 21LTSEn yeni LTS, yeni projeler için önerilir

    Uygulamanızın hangi sürümü gerektirdiğini bilmiyorsanız, projenin pom.xml (Maven) veya build.gradle (Gradle) dosyasındaki sourceCompatibility / java.version alanına bakın. Bu değer, sunucuya kuracağınız JDK sürümünün alt sınırını belirler.

    Debian ve Ubuntu Üzerinde OpenJDK Kurulumu#

    Debian tabanlı sistemlerde (Ubuntu, Debian, Linux Mint) paket yöneticisi apt'tir. Önce paket listenizi güncellemekle başlayın; bu adım atlanırsa depo dizininiz eski kalır ve paket bulunamayabilir.

    sudo apt update
    

    Belirli bir sürümü kurmak için openjdk-<sürüm>-jdk kalıbını kullanırsınız. Örneğin Java 17 kurmak için:

    sudo apt install -y openjdk-17-jdk
    

    Yalnızca çalıştırma ortamına ihtiyacınız varsa openjdk-17-jre paketini seçebilirsiniz, ancak yukarıda açıkladığımız gerekçelerle sunucuda tam JDK kurmanızı öneririz. Kurulumun başarılı olduğunu doğrulamak için sürümü sorgulayın:

    java -version
    javac -version
    

    Beklenen çıktı şuna benzer olmalıdır:

    openjdk version "17.0.11" 2024-04-16
    OpenJDK Runtime Environment (build 17.0.11+9-Ubuntu-1)
    OpenJDK 64-Bit Server VM (build 17.0.11+9-Ubuntu-1, mixed mode, sharing)
    

    Deponuzda hangi Java sürümlerinin bulunduğunu merak ediyorsanız arama yapabilirsiniz:

    apt search openjdk | grep -E 'openjdk-[0-9]+-jdk'
    

    Debian'ın kararlı deposu bazen en yeni Java sürümünü içermez. Java 21 veya daha yenisine ihtiyaç duyup depoda bulamazsanız, Eclipse Temurin (Adoptium) gibi bir dağıtımın APT deposunu ekleyebilir ya da doğrudan resmi tarball'ı /opt altına açıp bu rehberdeki update-alternatives yöntemiyle sisteme tanıtabilirsiniz. Temel Linux komutlarında rahat değilseniz, önce Linux temel komutları rehberine göz atmanız işinizi kolaylaştırır.

    RHEL, AlmaLinux ve Rocky Linux Üzerinde Kurulum#

    Red Hat ailesindeki dağıtımlarda (RHEL, AlmaLinux, Rocky Linux, Fedora, CentOS Stream) paket yöneticisi dnf'tir (eski sistemlerde yum). Paket adlandırması apt'ten biraz farklıdır; sürüm numarası paket adının içindedir ve genellikle "headless" bir varyant da sunulur.

    sudo dnf install -y java-17-openjdk-devel
    

    Buradaki -devel eki, javac dahil geliştirme araçlarını getirir; yani bu paket JDK karşılığıdır. Eğer sunucuda grafik arayüz yoksa (ki bir web sunucusunda genellikle yoktur) java-17-openjdk-headless paketi daha az bağımlılık çeker, fakat javac için yine -devel gerekir. Depoda mevcut sürümleri listelemek için:

    dnf search openjdk
    

    Kurulum sonrası doğrulama Debian tarafıyla aynıdır:

    java -version
    

    RHEL ailesinin güzel bir tarafı, aynı anda birden çok java-*-openjdk paketini yan yana kurabilmenize izin vermesidir. Örneğin hem Java 11 hem Java 17'yi kurup, hangisinin aktif olacağını alternatives mekanizmasıyla seçebilirsiniz. Bir sonraki bölümde tam olarak bunu ele alıyoruz.

    Birden Çok Sürümü update-alternatives ile Yönetmek#

    Gerçek dünyada tek bir sunucuda birden fazla uygulama, birbirinden farklı Java sürümleri talep edebilir. Eski bir raporlama servisi Java 8 isterken, yeni bir mikroservis Java 21 bekleyebilir. Linux'un update-alternatives (RHEL'de sadece alternatives) sistemi tam da bu ihtiyaç için vardır: aynı komuta (java, javac) karşılık gelen birden çok kurulumu yönetir ve /etc/alternatives altındaki sembolik bağlar üzerinden hangisinin varsayılan olacağını belirlemenizi sağlar.

    Önce ikinci bir sürüm kuralım. Ubuntu'da Java 11'i mevcut Java 17'nin yanına ekleyelim:

    sudo apt install -y openjdk-11-jdk
    

    Şimdi sistemde kayıtlı java alternatiflerini interaktif olarak görüntüleyip seçmek için:

    sudo update-alternatives --config java
    

    Karşınıza şuna benzer bir menü çıkar:

      Selection    Path                                         Priority   Status
    ------------------------------------------------------------
    * 0            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      auto mode
      1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java   1111      manual mode
      2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      manual mode
    
    Press <enter> to keep the current choice[*], or type selection number:
    

    İstediğiniz sürümün numarasını yazıp Enter'a bastığınızda varsayılan java o kuruluma sabitlenir. Çok önemli bir ayrıntı: java ve javac ayrı alternatiflerdir. Yani derleyiciyi de aynı sürüme almak için ikinci komutu da çalıştırmanız gerekir; aksi halde java 17'yi gösterirken javac 11'de kalabilir ve bu sinsi hatalara yol açar.

    sudo update-alternatives --config javac
    

    Kayıtlı tüm alternatifleri komut satırında hızlıca görmek için --list kullanabilirsiniz:

    update-alternatives --list java
    

    Manuel olarak /opt altına açtığınız bir tarball kurulumunu sisteme tanıtmak isterseniz, alternatifi elle ekleyebilirsiniz. Örneğin Temurin JDK 21'i /opt/jdk-21 altına açtığınızı varsayalım:

    sudo update-alternatives --install /usr/bin/java java /opt/jdk-21/bin/java 2100
    sudo update-alternatives --install /usr/bin/javac javac /opt/jdk-21/bin/javac 2100
    

    Sondaki sayı (2100) önceliktir; auto mode'da en yüksek öncelikli alternatif otomatik seçilir. Bu yöntemle dağıtım deposunda olmayan sürümleri bile düzenli bir şekilde yönetebilirsiniz.

    JAVA_HOME Ortam Değişkenini Doğru Ayarlamak#

    java -version çalışıyor olsa bile birçok araç (Maven, Gradle, Tomcat, Elasticsearch, Jenkins) sürümü doğrudan java komutundan değil, JAVA_HOME ortam değişkeninden okur. Bu değişken yanlış ya da eksikse, uygulamanız komut satırında çalışırken servis olarak ayağa kalkmayabilir. JAVA_HOME, JDK'nin kurulu olduğu kök dizini göstermelidir; bin alt klasörünü değil.

    Aktif java kurulumunun gerçek yolunu bulmak için sembolik bağları takip edin:

    readlink -f $(which java)
    

    Bu komut size /usr/lib/jvm/java-17-openjdk-amd64/bin/java gibi bir çıktı verir. JAVA_HOME için bin/java kısmını atmanız, yani /usr/lib/jvm/java-17-openjdk-amd64 yolunu kullanmanız gerekir.

    Değişkeni tüm kullanıcılar için kalıcı yapmak istiyorsanız /etc/profile.d altında yeni bir betik oluşturmak en temiz yöntemdir. Bu dosyayı bir kez kurup ileride sürüm değiştirdiğinizde yalnızca yolu güncellemeniz yeterli olur:

    sudo tee /etc/profile.d/java.sh > /dev/null <<'EOF'
    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
    export PATH=$JAVA_HOME/bin:$PATH
    EOF
    

    Değişikliğin mevcut oturumda etkin olması için betiği yeniden yükleyin ve doğrulayın:

    source /etc/profile.d/java.sh
    echo $JAVA_HOME
    

    Yalnızca kendi kullanıcınız için tanımlamak yeterliyse ~/.bashrc dosyasının sonuna aynı iki export satırını ekleyebilirsiniz. Kurumsal ortamlarda tek bir kullanıcının değil, sistem genelinin aynı JAVA_HOME'u görmesi genellikle tercih edilir; bu yüzden /etc/profile.d yaklaşımını öneriyoruz. Ortam değişkenleri ve kabuk yapılandırması konusunda derinleşmek isterseniz Linux temel komutları rehberi iyi bir başlangıçtır.

    Bir Java Uygulamasını (jar) Çalıştırmak#

    JDK kurulu ve JAVA_HOME ayarlı olduğuna göre artık bir uygulama çalıştırabiliriz. Java uygulamaları çoğunlukla tek bir çalıştırılabilir .jar dosyası olarak dağıtılır (özellikle Spring Boot "fat jar" üretir). Bir jar'ı çalıştırmanın en temel biçimi şudur:

    java -jar uygulama.jar
    

    Uygulamanıza harici parametre geçmeniz gerekiyorsa iki farklı yer vardır ve bu ayrım çok önemlidir. JVM'in kendisine ait ayarlar (bellek limiti, sistem özellikleri) -jar'dan önce; uygulamanın kendi argümanları ise -jar uygulama.jar'dan sonra yazılır:

    java -Xms256m -Xmx1024m -Dserver.port=9090 -jar uygulama.jar --spring.profiles.active=prod
    

    Burada -Xms256m başlangıç heap boyutunu, -Xmx1024m maksimum heap boyutunu belirler; -Dserver.port=9090 bir JVM sistem özelliğidir; --spring.profiles.active=prod ise Spring Boot'a geçen bir uygulama argümanıdır. Bellek limitlerini sunucunuzun RAM'ine göre ayarlamak önemlidir: -Xmx değerini sunucudaki toplam belleğin tamamına yakın vermeyin, işletim sistemi ve diğer servisler için pay bırakın.

    Bir jar'ın içinde hangi ana sınıfın çalışacağını merak ederseniz manifest dosyasına bakabilirsiniz:

    unzip -p uygulama.jar META-INF/MANIFEST.MF
    

    Bu noktada uygulamanız çalışır ama SSH oturumunuzu kapattığınız anda süreç de sonlanır. nohup java -jar uygulama.jar & gibi geçici çözümler test için uygundur, ancak production'da asla yeterli değildir: sunucu yeniden başladığında uygulama gelmez, çöktüğünde kendini toparlamaz ve logları düzgün toplayamazsınız. Kalıcı ve profesyonel çözüm bir sonraki bölümde: uygulamayı bir systemd servisi hâline getirmek.

    systemd Servisi Olarak Arka Planda Çalıştırmak#

    Production'da bir Java uygulamasını yönetmenin doğru yolu onu systemd servisi yapmaktır. Böylece uygulama sunucu açılışında otomatik başlar, çöktüğünde yeniden ayağa kaldırılır ve tüm çıktısı journald üzerinden merkezi log sistemine akar. Önce uygulamayı kendi ayrıcalıksız kullanıcısıyla çalıştırmak güvenlik açısından iyi bir alışkanlıktır; hiçbir uygulamayı gereksiz yere root ile çalıştırmayın.

    Adım adım kuralım. Önce özel bir kullanıcı ve dizin oluşturun, jar'ı yerleştirin:

    sudo useradd -r -s /usr/sbin/nologin javaapp
    sudo mkdir -p /opt/javaapp
    sudo cp uygulama.jar /opt/javaapp/
    sudo chown -R javaapp:javaapp /opt/javaapp
    

    Ardından servis birim dosyasını /etc/systemd/system/javaapp.service olarak oluşturun:

    [Unit]
    Description=Clou.TR Java Uygulamasi
    After=network.target
    
    [Service]
    Type=simple
    User=javaapp
    Group=javaapp
    WorkingDirectory=/opt/javaapp
    Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
    ExecStart=/usr/lib/jvm/java-17-openjdk-amd64/bin/java -Xmx1024m -jar /opt/javaapp/uygulama.jar
    SuccessExitStatus=143
    Restart=on-failure
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
    

    Birkaç ayrıntı önemlidir. ExecStart içinde java komutunun tam yolunu vermek en güvenlisidir, çünkü servis ortamı sizin kabuğunuzun PATH'ini miras almaz. SuccessExitStatus=143 satırı, JVM'in SIGTERM ile kapatıldığında döndürdüğü 143 çıkış kodunu "başarılı" sayarak servisin gereksiz yere hatalı görünmesini engeller. Restart=on-failure ise uygulama beklenmedik şekilde çökerse systemd'nin onu 10 saniye içinde yeniden başlatmasını sağlar.

    Dosyayı kaydettikten sonra servisi tanıtın, başlatın ve açılışa ekleyin:

    sudo systemctl daemon-reload
    sudo systemctl enable --now javaapp
    sudo systemctl status javaapp
    

    Uygulamanın anlık loglarını takip etmek için:

    sudo journalctl -u javaapp -f
    

    Bu yapı, tek bir jar'dan kurumsal bir mikroservise kadar her ölçekte güvenilir çalışır. systemd birim dosyalarının detaylarını, bağımlılık sıralamasını ve gelişmiş yeniden başlatma politikalarını systemd servis yönetimi rehberinde daha derinlemesine bulabilirsiniz. Java uygulamanızın önüne bir ters proxy (Nginx) koyup HTTPS sonlandırması yapmak isterseniz, bir SSL sertifikası ile trafiği şifrelemek de bu aşamada mantıklı bir adımdır.

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

    Kurulum ne kadar dikkatli yapılırsa yapılsın birkaç klasik hata hemen herkesin başına gelir. En sık görüleni UnsupportedClassVersionError mesajıdır. Bu hata, uygulamanın sizin sunucudaki Java sürümünüzden daha yeni bir sürümle derlendiğini söyler; örneğin Java 21 ile derlenmiş bir jar'ı Java 17 üzerinde çalıştırmaya çalışırsanız bununla karşılaşırsınız. Çözüm, ya sunucuya gereken sürümü kurmak ya da uygulamayı hedef sürüme göre yeniden derlemektir.

    İkinci klasik sorun, JAVA_HOME'un servis ortamında görünmemesidir. Komut satırında her şey çalışırken systemd servisi "java bulunamadı" diye başarısız oluyorsa, bunun sebebi neredeyse her zaman servisin sizin kabuk profilinizi okumamasıdır. Yukarıdaki birim dosyasında olduğu gibi Environment=JAVA_HOME=... satırını ve ExecStart'ta tam yolu açıkça belirtmek bu sorunu kökten çözer. Üçüncü olarak, bellek darboğazları vardır: küçük bir VPS'te -Xmx değerini fazla yüksek verirseniz uygulama OutOfMemoryError ile ya da OOM-killer tarafından öldürülerek çöker. Sunucunuzun kaynak planlamasını uygulamanın gerçek ihtiyacına göre yapmak, bu yüzden kritik önemdedir.

    Son bir ipucu: alternatives ile varsayılan sürümü değiştirdiğinizde çalışan servisleri yeniden başlatmayı unutmayın. Zaten ayakta olan bir JVM, kendisi başlatıldığı sürümle çalışmaya devam eder; yeni sürümü ancak süreç yeniden başlatıldığında görür.

    Sıkça Sorulan Sorular#

    JDK mi JRE mi kurmalıyım?#

    Sunucuda çoğunlukla hazır bir .jar çalıştıracak olsanız bile JDK kurmanızı öneririz. JDK, JRE'nin sağladığı çalıştırma ortamına ek olarak thread dump alma, heap inceleme ve gerektiğinde kaynaktan derleme araçlarını da içerir. Bu teşhis araçları bir production sorununda paha biçilmez olur ve JDK'nin ek disk maliyeti neredeyse önemsizdir.

    java -version çalışıyor ama javac bulunamıyor, sorun ne?#

    Bu durum genellikle sistemde tam JDK yerine yalnızca JRE'nin kurulu olduğunu ya da update-alternatives üzerinde java ile javac'in farklı sürümlere işaret ettiğini gösterir. Debian tarafında openjdk-<sürüm>-jdk, RHEL tarafında ise java-<sürüm>-openjdk-devel paketini kurduğunuzdan emin olun. Ardından sudo update-alternatives --config javac komutuyla derleyiciyi de doğru sürüme sabitleyin.

    JAVA_HOME neyi göstermeli, bin/java yolunu mu?#

    JAVA_HOME, JDK'nin kurulu olduğu kök dizini göstermelidir; yani bin/java'yı değil, onun bir üstündeki klasörü. Örneğin doğru değer /usr/lib/jvm/java-17-openjdk-amd64 iken, /usr/lib/jvm/java-17-openjdk-amd64/bin/java yanlıştır. Aktif yolu bulmak için readlink -f $(which java) komutunu çalıştırıp sondaki bin/java kısmını çıkarabilirsiniz.

    Aynı sunucuda birden fazla Java sürümü tutabilir miyim?#

    Evet, bu tamamen desteklenen bir senaryodur. Farklı sürümleri yan yana kurup update-alternatives (RHEL'de alternatives) ile aralarında geçiş yapabilirsiniz. Hatta sistem varsayılanını değiştirmeden, belirli bir uygulamanın systemd birim dosyasında ExecStart yoluyla ona özel bir Java sürümünü sabitleyebilirsiniz; böylece her uygulama kendi gereksinim duyduğu sürümle çalışır.

    Uygulamayı nohup yerine neden systemd ile çalıştırmalıyım?#

    nohup ... & yalnızca hızlı bir test için idare eder; production için yetersizdir. systemd ile uygulamanız sunucu yeniden başladığında otomatik ayağa kalkar, çöktüğünde yeniden başlatılır, ayrıcalıksız bir kullanıcıyla güvenli çalışır ve tüm logları journalctl üzerinden merkezi biçimde toplanır. Bu yetenekler ciddi bir servis için pazarlık konusu olmayan gereksinimlerdir.

    Hangi Java sürümünü seçmeliyim?#

    Yeni bir proje başlatıyorsanız güncel bir LTS sürümü (bu rehberin yazıldığı dönemde Java 21) tercih edin; LTS sürümler uzun süre güvenlik güncellemesi alır. Mevcut bir uygulamayı taşıyorsanız, projenin pom.xml veya build.gradle dosyasındaki Java sürüm ayarına bakıp en az o sürümü kurun. Emin değilseniz, uygulamanın derlendiği sürümle aynısını kullanmak en güvenli yoldur.

    Kapanış#

    Java'yı Linux'a kurmak, ilk bakışta tek bir apt install komutundan ibaret görünse de işin kalitesi ayrıntılarda saklıdır: doğru sürümü seçmek, update-alternatives ile sürümleri düzenli yönetmek, JAVA_HOME'u kalıcı ve tutarlı tanımlamak ve uygulamayı systemd ile güvenli biçimde arka planda çalıştırmak. Bu dört adımı bir kez doğru kurduğunuzda, ister bir mikroservis ister kurumsal bir uygulama olsun, sunucunuz Java iş yükleri için sağlam bir temele kavuşur.

    Bu altyapıyı üzerine kuracağınız güçlü bir sunucu arıyorsanız Clou.TR yanınızda. Java uygulamalarınız için tam kök erişimli VDS sunucularımıza veya esnek sanal sunucu seçeneklerimize göz atabilir, kurulum ve bakımı bize bırakmak isterseniz sunucu yönetimi hizmetimizden faydalanabilirsiniz. Uygulamanızı yayına alırken trafiği şifrelemek için SSL sertifikası, saldırılara karşı DDoS koruma ve düzenli yedekleme çözümlerimizle projenizi baştan sona güvenceye alın. Sorularınız için destek ekibimiz her zaman bir tık uzağınızda.

    JavaJDKRuntime

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.