in

Java 25 LTS: Kurumsal Projelerde Geçiş Planı ve Yenilikler

Java 21 sanal thread'lerle büyük sıçramaydı; Java 25 LTS ise kurumsal projelerin dört yıl güvenle üzerinde duracağı 'cilalama' sürümü. 21'den 25'e gelen kalıcı yenilikleri (Scoped Values, kompakt nesne başlıkları, AOT önbelleği, esnek kurucular), performans kazançlarını ve adım adım geçiş planını kütüphane uyumluluğu ve tuzaklarla birlikte anlatıyoruz.

Java 21'den Java 25 LTS'e geçişte gelen yenilikleri ve geçiş adımlarını gösteren zaman çizelgesi

Java 21, sanal thread'ler ve desen eşleştirmeyle kurumsal Java'nın son on yıldaki en büyük sıçramasıydı. Java 25 LTS (Eylül 2025) ise farklı bir sürüm: devrim değil, cilalama. 22, 23 ve 24'te olgunlaşan özellikler kalıcı hale geldi, JVM'in başlangıç süresi ve bellek kullanımı görünür biçimde iyileşti, eski bagaj (SecurityManager, 32-bit x86) atıldı. Kurumsal projeler için soru "geçelim mi" değil, "ne zaman ve nasıl" sorusudur.

Bu yazıda LTS'ten LTS'e geçiş mantığını, Java 21 ile 25 arasında gelen kalıcı yenilikleri ve kurumsal değerlerini, performans kazançlarını, adım adım geçiş planını, kütüphane uyumluluğunu ve sahada gördüğümüz tuzakları anlatıyoruz.

Neden LTS'ten LTS'e?

LTS

Çıkış

Öne çıkan

Durum

Java 8

2014

Lambda, Stream

Yalnızca ücretli/uzatılmış destek; güvenlik riski

Java 11

2018

Modül sistemi, HTTP Client

Destek sona eriyor; geçiş şart

Java 17

2021

Sealed, record, text block

Yaygın; birçok dağıtımda 2029'a kadar güncelleme

Java 21

2023

Sanal thread, desen eşleştirme, sequenced collections

Güncel kurumsal taban

Java 25

2025

Scoped Values, AOT, kompakt nesne başlıkları

Yeni taban; bir sonraki LTS 2027'de (Java 29)

Altı ayda bir çıkan ara sürümler (22, 23, 24) yalnızca bir sonraki sürüme kadar güncelleme alır; kurumsal üretim bunları atlar ve iki yılda bir LTS'e geçer. LTS'e geçmeyi ertelemek, güvenlik yamalarını ve kütüphane desteğini kaybetmek demektir: kütüphaneler taban sürümlerini yükseltir (Spring Boot 3 için 17, Spring Framework 7 için 17, bir sonraki nesillerde 21) ve eski JDK'da kalan proje güncelleme alamaz hale gelir.

21'den 25'e gelen kalıcı yenilikler

Özellik

Sürüm / JEP

Kurumsal değeri

Foreign Function & Memory API

22 / JEP 454

JNI olmadan native kütüphane çağrısı; SAP JCo gibi native köprülerin geleceği

Adsız değişkenler ve desenler (_)

22 / JEP 456

Okunabilir catch ve desen bloklarında gürültüyü azaltır

Stream Gatherers

24 / JEP 485

Stream'e özel ara işlemler (pencereleme, gruplama) — toplu veri işlemede

Class-File API

24 / JEP 484

ASM yerine standart bytecode API'si; Spring, Hibernate gibi çerçevelerin yeni sürümlerle uyumu

AOT sınıf yükleme ve bağlama (Leyden)

24 / JEP 483; 25 / JEP 514, 515

Başlangıç süresi belirgin düşer; eğitim koşusu ile AOT önbelleği

Sanal thread'lerde pinning düzeltmesi

24 / JEP 491

synchronized blokları artık taşıyıcı thread'i kilitlemez; eski kütüphanelerle sanal thread güvenli

Scoped Values

25 / JEP 506

ThreadLocal'ın sanal thread'e uygun, değişmez ve ucuz alternatifi; istek bağlamı, kiracı, izleme

Modül import bildirimi

25 / JEP 511

import module java.base; — script ve küçük araçlarda

Kompakt kaynak dosyaları ve instance main

25 / JEP 512

Eğitim ve script; kurumsal kodda dolaylı fayda

Esnek kurucu gövdeleri

25 / JEP 513

super() öncesi doğrulama; alt sınıf kurucuları temizlenir

Anahtar türetme (KDF) API

25 / JEP 510

HKDF gibi standart KDF'ler; şifreleme kodunda üçüncü taraf bağımlılığı azalır

Kompakt nesne başlıkları

25 / JEP 519 (seçmeli)

Heap %10–20 küçülür; -XX:+UseCompactObjectHeaders

Generational ZGC varsayılan, Generational Shenandoah

23 / JEP 474; 25 / JEP 521

Düşük duraklamalı GC'ler daha az CPU ve bellekle

JFR iyileştirmeleri

25 / JEP 518, 520

Metot zamanlama ve izleme; üretimde daha güvenli profil

Kaldırılanlar: SecurityManager kalıcı olarak devre dışı (24 / JEP 486), 32-bit x86 portu (25 / JEP 503), generational olmayan ZGC (24 / JEP 490). Önizlemede kalanlar (Structured Concurrency, Stable Values, ilkel tiplerde desen) üretim koduna girmez.

Üç yenilik, üç örnek

// 1) Scoped Values: istek bağlamı için ThreadLocal yerine — değişmez, sanal thread'e uygun, otomatik temizlenir
public final class Baglam {
    public static final ScopedValue<KiraciKimligi> KIRACI = ScopedValue.newInstance();
}

// filtrede
ScopedValue.where(Baglam.KIRACI, kiraci).run(() -> chain.doFilter(req, res));

// herhangi bir katmanda
KiraciKimligi k = Baglam.KIRACI.get();      // bağlam dışında çağrılırsa NoSuchElementException: sızıntı imkânsız
// 2) Stream Gatherers: sabit boyutlu pencerelerle toplu işleme (örneğin 500'lük partiler hâlinde ERP'ye gönderim)
siparisler.stream()
    .gather(Gatherers.windowFixed(500))
    .forEach(parti -> erp.topluGonder(parti));
// 3) Esnek kurucu gövdesi: super() öncesi doğrulama ve alan hazırlığı
public class KurumsalMusteri extends Musteri {
    private final VergiNo vergiNo;
    public KurumsalMusteri(String ad, String vergiNo) {
        if (vergiNo == null || vergiNo.length() != 10) throw new IllegalArgumentException("vergi no");
        this.vergiNo = new VergiNo(vergiNo);           // artık super()'den önce izinli
        super(ad);
    }
}

Performans: ölçülebilir kazançlar

  • Başlangıç süresi: AOT önbelleği (eğitim koşusuyla üretilen -XX:AOTCache) Spring Boot uygulamalarında başlangıcı CDS'e göre bir adım daha kısaltır; Kubernetes'te ölçekleme ve dağıtım hızlanır (bkz. Kubernetes'te Spring Boot).

  • Bellek: Kompakt nesne başlıkları küçük nesne yoğun uygulamalarda (DTO, entity, koleksiyon) heap'i %10–20 düşürür; aynı konteynerde daha fazla iş ya da daha küçük konteyner.

  • Sanal thread'ler: Pinning düzeltmesiyle JDBC sürücüleri ve eski kütüphanelerdeki synchronized bloklar artık verimi düşürmez; 21'de sanal thread'i denemekten vazgeçmiş ekipler 25'te yeniden denemelidir.

  • GC: Generational ZGC ile düşük duraklama artık dev heap gerektirmez.

Adım adım geçiş planı

Adım

Ne yapılır

Süre (tipik)

1. Envanter

Bağımlılık listesi ve JDK 25 uyumlu sürümleri: Spring Boot 3.5.x (güncel yama) ya da 4.x, Hibernate 6.6+/7, Jackson, Mockito ve ByteBuddy (sınıf dosyası sürümü 69), Lombok, MapStruct, Testcontainers, JDBC sürücüleri

1–2 gün

2. Derleme ve test

CI'da ikinci bir iş: --release 25 ile derle, tüm testleri koştur; kırılanları listele

1–3 gün

3. Uyarıları kapat

sun.misc.Unsafe bellek erişimi uyarıları (JEP 498) → kütüphane güncelle; JNI/FFM için --enable-native-access=ALL-UNNAMED; SecurityManager kullanımı varsa kaldır

1–5 gün

4. Çalışma zamanı

Temel imajı 25'e al; JVM bayraklarını gözden geçir (-XX:+UseCompactObjectHeaders'ı yük testinde dene); AOT önbelleği için eğitim koşusu

2–3 gün

5. Kademeli dağıtım

Test → staging → üretimde canary; GC logu, gecikme ve bellek metriklerini 21 ile karşılaştır

1–2 hafta

Kod tarafında zorunlu değişiklik genellikle yoktur: 21'de derlenen kod 25'te çalışır. Süre, kütüphane sürümleri ve uyarıların kapatılmasından gelir; bu yüzden 1. adım en kritik olanıdır.

Tuzaklar

  1. Eski ByteBuddy/Mockito: Test aşamasında "Unsupported class file major version 69"; çözüm sürüm yükseltmektir, -Dnet.bytebuddy.experimental=true geçici çaredir.

  2. Unsafe kullanan kütüphaneler: Uyarı bugün, hata gelecek sürümlerde; eski Netty, Hazelcast, bazı serileştiriciler. Şimdi güncelleyin.

  3. Kompakt başlıkları test etmeden açmak: Çoğu uygulamada saf kazanç, ama JNI ile nesne başlığına erişen kütüphaneler (nadir) etkilenir; yük testi şart.

  4. Spring Boot 2.x'ten doğrudan 25: Olmaz; önce 3.x'e (Jakarta ad alanı) geçiş, sonra JDK. İki büyük değişikliği aynı sürümde yapmayın.

  5. Derleyici hedefini unutmak: Maven'da maven.compiler.release 21'de kalırsa dil özellikleri kullanılamaz; bilinçli olarak yükseltin.

Sık sorulan sorular

Java 17'den doğrudan 25'e geçilir mi?

Evet; 17 → 25 tek adımda yapılır ve aradaki tüm kazanımları (sanal thread, desen eşleştirme, record pattern) birlikte getirir. Plan aynıdır; envanter adımı biraz daha uzundur.

Hangi JDK dağıtımı?

Eclipse Temurin, Amazon Corretto, Azul Zulu, Red Hat build of OpenJDK ve Oracle JDK aynı OpenJDK kaynak kodundan gelir; fark destek süresi, lisans ve ek araçlardadır. Konteyner imajları için Temurin yaygın ve sorunsuzdur; kurumsal destek sözleşmesi gerekiyorsa buna göre seçilir.

Sanal thread'i açmak için geçiş şart mı?

Hayır, 21'de de var; ama 24'teki pinning düzeltmesi sanal thread'i eski kütüphanelerle güvenli kılan değişikliktir. Sanal thread'i ciddi kullanacak projeler için 25 doğru taban.

Sonuç

Java 25 LTS, kurumsal projelerin dört yıl güvenle üzerinde duracağı tabandır: daha hızlı başlangıç, daha küçük heap, daha güvenli sanal thread'ler, ThreadLocal'sız bağlam yönetimi ve temizlenmiş bir platform. Geçiş bir kod projesi değil, bir envanter ve doğrulama projesidir; iyi bir CI ile birkaç haftada tamamlanır.

Mevcut Java uygulamalarınızı 25'e taşımak, kütüphane envanterini çıkarmak ve performans kazançlarını ölçmek için bakım ve destek hizmetimize göz atabilirsiniz.