JDK 8'den 21'e Geçiş — Derleme Yeşil, Rapor Sunucusu Neden Açılmadı?
Önce şunu oku: Java 8'den 21'e — Her Özellik Bir Hata Sınıfı
30 saniyede özet
Çok modüllü bir projeyi JDK 21'e taşırken üç ayrı şey kırılır: ortak modül eski sunucunun okuyamadığı sürümde derlenir, JDK'dan çıkan JAXB gibi parçalar eksik kalır, iç API'lere uzanan eski kütüphaneler durur.
Evde yeni bir oynatıcı aldın ve tatil videosunu onun yeni formatında diske yazdın. Herkes izledi, sonra disk babaanneye gitti. Onun eski oynatıcısı diski okuyamadı.
-
Bayt: Bütün projeyi JDK 21'e taşıdık. Derleme yeşil, testler yeşil!
-
Sen: Rapor uygulaması hâlâ eski sunucuda, JDK 8 ile çalışıyor. O açılmadı.
-
Bayt: Ama rapor koduna dokunmadık ki! Sadece ortak modülü yeniden derledik.
-
Bayt: Ortak modül herkese gidiyor. En eski oynatıcı onu okuyabilmeli.
Önce derleyiciyi değiştir, hedefi sonra
Bir JDK iki iş yapar: kodu derler ve üretilen sınıfları çalıştırır. Derleyiciye “bu sınıfları Java 8 için üret” demek mümkündür: Maven’da bu maven.compiler.release ayarıdır.
Bu yüzden geçiş iki adımdır. Önce bütün projeyi JDK 21 ile derle ama hedefi 8’de bırak; eski eklentiler ve araçlar bu adımda dökülür. Uygulamalar JDK 21 üstünde koşmaya başlayınca hedefi yükselt.
Kafam karıştı, daha basit anlat
Önce derleyiciyi değiştir. Hedef sürümü, uygulamalar yeni JVM’e geçince yükselt.
JDK 21 ile derleyip sınıfları Java 8 için üretmek mümkün mü?
Çok modüllü bir projede JDK geçişine hangi sırayla başlamak daha güvenlidir?
Ortak modül en eski runtime’a bakar
Çok modüllü bir Maven projesinde Maven reactorÇok modüllü bir Maven projesinde modülleri bağımlılık sırasına dizip tek komutla kuran mekanizma. Önce kütüphaneler, sonra onları kullananlar kurulur.Sözlükte gör →, modülleri bağımlılık sırasıyla kurar: önce ortak kütüphane, sonra onu kullanan uygulamalar. Ortak modül birden çok uygulamaya gider.
common modülü --release 21 ile derlendi. settlement ve trading JDK 21'de koşuyor; report.war ise hâlâ JDK 8 kurulu bir sunucuda. Derleme yeşil. report.war açılır mı? Cevabı göster
Açılmaz. Sunucu, common’ın sınıflarını yüklerken UnsupportedClassVersionError verir. Sınıflar 65 sürümünde; JDK 8 en çok 52’yi okur.
Adım adım oku
- Evde yeni oynatıcı.
- Tatil videosu yeni formatta.
- Babaannenin oynatıcısı okuyamadı.
- Ortak diski en eski oynatıcıya göre yaz.
Her derlenmiş sınıfın içinde bir sınıf dosyası sürümüDerlenmiş her .class dosyasında yazan sürüm numarası: Java 8 için 52, Java 21 için 65. Bir JVM kendinden yeni sürümü okumaz.Sözlükte gör → yazar: Java 8 için 52, Java 21 için 65. Bir JVM kendinden yeni sürümü okumaz. Derleme bunu yakalamaz, çünkü derleme JDK 21’de yapılır.
Kafam karıştı, daha basit anlat
Ortak modülü, onu kullanan en eski JVM’in okuyabileceği sürümde derle.
common modülü --release 21 ile derlendi. JDK 8 kurulu sunucudaki report.war bu modülü yükleyince ne olur?
Ortak bir modülün hedef sürümünü ne belirler?
JDK’dan çıkanlar, kapanan kapılar
JDK 11 ile bazı Java EE parçaları JDK’dan çıkarıldı. XML’i nesneye çeviren JAXB bunlardan biridir: JDK 8’de hazır gelir, JDK 11 ve sonrasında açık bir bağımlılık olarak eklenmesi gerekir.
İkinci kırılma reflection’dadır. JDK 17 ile güçlü kapsüllemeJDK 17 ile zorunlu olan kural: JDK'nın iç sınıflarına reflection ile erişilemez. Eski kütüphaneler InaccessibleObjectException alır.Sözlükte gör → zorunlu oldu: JDK’nın iç sınıflarına reflection ile uzanan eski kütüphaneler InaccessibleObjectException alır. Çözüm çoğu zaman kütüphanenin güncel sürümüdür; --add-opens yalnızca geçici bir yamadır.
Spring Boot 3 ayrıca en az Java 17 ister ve javax.* paketlerini jakarta.* olarak değiştirir. Bu, geçişi bir import değişikliğine de çevirir.
Kafam karıştı, daha basit anlat
Eksik parçayı bağımlılık olarak ekle. İç API’lere uzanan kütüphaneyi güncelle.
JDK 8'de çalışan, JAXB ile XML yazan modül JDK 21'de derlenmiyor. En doğru çözüm?
Kendin gör
Dört modüllü proje JDK 21’e geçiyor
Tohum 188729- common (ortak kütüphane)· sırada bekliyor
- settlement (JDK 21)· sırada bekliyor
- trading (JDK 21)· sırada bekliyor
- report.war (JDK 8 sunucu)· sırada bekliyor
Şu an ne oldu?
Reactor modülleri sırayla kuruyor
Önce ortak modül, sonra onu kullanan uygulamalar.
Görevler0/2
Derleme ve testler geçsin, rapor sunucusu açılmasınaçık
İpucu
JAXB’yi ekle, kütüphaneyi güncelle, common’ı 21’de bırak.
Dört modül de ayağa kalksınaçık
İpucu
Ortak modülü en eski runtime’a göre derle.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Dört modülden üçü kırıldı: biri derlemede, biri testte, biri sunucuda. Üç kırılmanın nedeni ayrı.
- JAXB’yi ekle ve kütüphaneyi güncelle. Derleme ve testler yeşil; report.war yine açılmadı.
- common’ı —release 8 yap. Dört modül de ayakta: ortak modül, en eski runtime’a göre derlendi.
Simülatörde JAXB eklendi ve kütüphane güncellendi; derleme ve testler yeşil. Neden report.war hâlâ açılmıyor?
Tuzaklar
Varsayılan karakter seti. JDK 18 ile varsayılan karakter seti her yerde UTF-8 oldu. Karakter seti vermeden dosya okuyan eski kod, Windows sunucuda Türkçe harfleri artık farklı okuyabilir; dosyayı okurken karakter setini açıkça yaz.
Eski build eklentileri. Eski bir JaCoCo ya da Surefire sürümü, yeni sınıf sürümünü tanımayabilir. JDK’yı değiştirmeden önce eklentileri güncelle.
Jenkins ajanları. Pipeline hangi JDK ile koşuyor, bunu şansa bırakma. maven-enforcer-plugin ile beklenen Java sürümünü build’in ilk adımında kontrol et.
Kafam karıştı, daha basit anlat
Karakter setini açık yaz, eklentileri güncelle, build’in hangi JDK’da koştuğunu kontrol et.
Karakter seti vermeden dosya okuyan eski kod, JDK 18 sonrası Windows sunucuda Türkçe harfleri bozuk okumaya başladı. Neden?
Aşağıda bir trading projesinin geçiş ayarları var: ana POM, rapor modülü ve Jenkins pipeline.
Derinleş · Trading platformu: çok modüllü projede JDK 21 geçişi 4 dosya · ~106 satır · ilk okumada atlayabilirsin
Kendini sına
JDK 21 ile derlenmiş bir sınıf, hedef 8 verilirse JDK 8'de çalışabilir.
Eski bir mock kütüphanesinin testleri JDK 17'de InaccessibleObjectException ile düşüyor. En iyi kalıcı çözüm?
Aklında kalacak üç şey
- 1 Ortak bir modülün hedef sürümü, onu kullanan en eski runtime'dır. Derlemenin geçmesi, eski sunucunun o sınıfları okuyabileceği anlamına gelmez.
- 2 JDK 11 ile JAXB gibi Java EE parçaları JDK'dan çıktı; JDK 17 ile JDK'nın iç sınıflarına reflection kapısı kapandı. İkisi de açık bir bağımlılık ya da kütüphane güncellemesiyle çözülür.
- 3 Geçiş iki adımdır: önce derleyiciyi ve araçları JDK 21'e taşı, eski hedefi koru; uygulamalar yeni JVM'de koşunca hedefi modül modül yükselt.