İçeriğe geç

JDK 8'den 21'e Geçiş — Derleme Yeşil, Rapor Sunucusu Neden Açılmadı?

İleri 10 dk Sık karşılaşılır

Ö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ı.

  1. Bayt: Bütün projeyi JDK 21'e taşıdık. Derleme yeşil, testler yeşil!

  2. Sen: Rapor uygulaması hâlâ eski sunucuda, JDK 8 ile çalışıyor. O açılmadı.

  3. Bayt: Ama rapor koduna dokunmadık ki! Sadece ortak modülü yeniden derledik.

  4. 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.

Hızlı kontrolBaşlangıç

JDK 21 ile derleyip sınıfları Java 8 için üretmek mümkün mü?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Çok modüllü bir projede JDK geçişine hangi sırayla başlamak daha güvenlidir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

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.

Ortak diski en eski oynatıcıya göre yaz.
Adım adım oku
  1. Evde yeni oynatıcı.
  2. Tatil videosu yeni formatta.
  3. Babaannenin oynatıcısı okuyamadı.
  4. 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.

Hızlı kontrolOrta

common modülü --release 21 ile derlendi. JDK 8 kurulu sunucudaki report.war bu modülü yükleyince ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Ortak bir modülün hedef sürümünü ne belirler?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

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.

Hızlı kontrolOrta

JDK 8'de çalışan, JAXB ile XML yazan modül JDK 21'de derlenmiyor. En doğru çözüm?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

Dört modüllü proje JDK 21’e geçiyor

Tohum 188729
  1. common (ortak kütüphane)· sırada bekliyor
  2. settlement (JDK 21)· sırada bekliyor
  3. trading (JDK 21)· sırada bekliyor
  4. report.war (JDK 8 sunucu)· sırada bekliyor
Hız
Adım 0

Ş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.

  1. Varsayılanla oynat. Dört modülden üçü kırıldı: biri derlemede, biri testte, biri sunucuda. Üç kırılmanın nedeni ayrı.
  2. JAXB’yi ekle ve kütüphaneyi güncelle. Derleme ve testler yeşil; report.war yine açılmadı.
  3. common’ı —release 8 yap. Dört modül de ayakta: ortak modül, en eski runtime’a göre derlendi.
Hızlı kontrolİleri

Simülatörde JAXB eklendi ve kütüphane güncellendi; derleme ve testler yeşil. Neden report.war hâlâ açılmıyor?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanı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.

Hızlı kontrolOrta

Karakter seti vermeden dosya okuyan eski kod, JDK 18 sonrası Windows sunucuda Türkçe harfleri bozuk okumaya başladı. Neden?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

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
Proje dosyaları

pom.xml Ana POM: derleyici sürümü tek yerde; JDK 21 ile derlenir, varsayılan hedef 21.

pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.bank.trading</groupId>
<artifactId>trading-platform</artifactId>
<version>4.0.0</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>settlement</module>
<module>trading</module>
<module>report</module>
</modules>
<properties>
<!-- Every module targets 21 unless it says otherwise. -->
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>require-jdk-21</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<requireJavaVersion><version>[21,)</version></requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

common/ pom.xml common modülü: rapor uygulaması JDK 8'de koştuğu sürece 8 hedefinde kalır.

common/pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bank.trading</groupId>
<artifactId>trading-platform</artifactId>
<version>4.0.0</version>
</parent>
<artifactId>common</artifactId>
<properties>
<!-- report.war still runs on a JDK 8 server: class file version 52.
Raise this only after that server moves to JDK 21. -->
<maven.compiler.release>8</maven.compiler.release>
</properties>
</project>

settlement/ pom.xml settlement modülü: JDK'dan çıkan JAXB artık açık bir bağımlılık.

settlement/pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bank.trading</groupId>
<artifactId>trading-platform</artifactId>
<version>4.0.0</version>
</parent>
<artifactId>settlement</artifactId>
<dependencies>
<dependency>
<groupId>com.bank.trading</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- JAXB left the JDK in 11; the settlement file writer needs it explicitly. -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>4.0.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

Jenkinsfile Jenkinsfile: pipeline JDK 21 ile koşar; enforcer yanlış JDK'yı ilk adımda durdurur.

Jenkinsfile
pipeline {
agent any
tools {
jdk 'jdk-21'
maven 'maven-3.9'
}
stages {
stage('Build') {
steps {
// The enforcer stops the build here if the agent has the wrong JDK.
sh 'mvn -B clean verify'
}
}
stage('Class versions') {
steps {
// report.war must stay readable by its JDK 8 server: expect "major version: 52".
sh 'javap -v -cp common/target/classes com.bank.trading.common.Money | grep "major version"'
}
}
}
}

Kendini sına

Şimşek turu1/4

JDK 21 ile derlenmiş bir sınıf, hedef 8 verilirse JDK 8'de çalışabilir.

Soru 1/3İleri

Eski bir mock kütüphanesinin testleri JDK 17'de InaccessibleObjectException ile düşüyor. En iyi kalıcı çözüm?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 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. 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. 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.
0/4 kart bu dersten toplandı