Java 6/7/8'de JDK'nın bir parçası olarak sağlanan JAXB API sınıflarını kullanan bazı kodlarım var. Aynı kodu Java 9 ile çalıştırdığımda, çalışma zamanında JAXB sınıflarının bulunamadığını belirten hatalar alıyorum.
JAXB sınıfları Java 6'dan beri JDK'nın bir parçası olarak sağlanmıştır, peki Java 9 neden artık bu sınıfları bulamıyor?
JAXB API'leri Java EE API'leri olarak kabul edilir ve bu nedenle Java SE 9'da artık varsayılan sınıf yolunda yer almaz. Java 11'de JDK'dan tamamen kaldırılırlar.
Java 9 modül kavramını getirmiştir ve varsayılan olarak java.se
aggregate modülü sınıf yolunda (ya da daha doğrusu modül yolunda) mevcuttur. Adından da anlaşılacağı gibi, java.se
aggregate modülü, geleneksel olarak Java 6/7/8 ile birlikte gelen Java EE API'lerini içermez.
Neyse ki, JDK 6/7/8'de sağlanan bu Java EE API'leri hala JDK'da, ancak varsayılan olarak sınıf yolunda değiller. Ekstra Java EE API'leri aşağıdaki modüllerde sağlanır:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Hızlı ve kirli çözüm: (yalnızca JDK 9/10)
JAXB API'lerini çalışma zamanında kullanılabilir hale getirmek için aşağıdaki komut satırı seçeneğini belirtin:
--add-modules java.xml.bind
Ancak bunun Java 8 ile çalışması için hala ihtiyacım var!!!
Eski bir JDK ile --add-modules
belirtmeyi denerseniz, tanınmayan bir seçenek olduğu için patlayacaktır. İki seçenekten birini öneririm:
JDK_JAVA_OPTIONS
ortam değişkenini kullanarak ayarlayabilirsiniz. Bu ortam değişkeni Java 9+ için java
başlatıcısı tarafından otomatik olarak okunur.Alternatif hızlı çözüm: (yalnızca JDK 9/10)
Yukarıdaki Java EE modüllerinin tümünü --add-modules java.se.ee
seçeneğini belirterek çalışma zamanında kullanılabilir hale getirebileceğinizi unutmayın. java.se.eemodülü, yukarıdaki Java EE API modüllerinin yanı sıra
java.se.eemodülünü de içeren bir toplu modüldür. Java 11
de java.se.ee
kaldırıldığı için bu Java 11 üzerinde çalışmaz.
Uzun vadeli uygun çözüm: (JDK 9 ve sonrası)
Yukarıda listelenen Java EE API modüllerinin tümü @Deprecated(forRemoval=true)
olarak işaretlenmiştir, çünkü Java 11'de kaldırılması planlanmıştır. Dolayısıyla --add-module
yaklaşımı artık Java 11'de kutudan çıkar çıkmaz çalışmayacaktır.
Java 11 ve sonrasında yapmanız gereken şey, Java EE API'lerinin kendi kopyasını sınıf yoluna veya modül yoluna dahil etmektir. Örneğin, JAX-B API'lerini aşağıdaki gibi bir maven bağımlılığı olarak ekleyebilirsiniz:
<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
JAXB hakkında daha fazla bilgi için JAXB Reference Implementation page adresine bakın.
Java modülerliği hakkında tüm ayrıntılar için bkz JEP 261: Modül Sistemi
Gradle veya Android Studio geliştiricisi için: (JDK 9 ve sonrası)
Aşağıdaki bağımlılıkları build.gradle dosyanıza ekleyin:
bağımlılıklar {
// JDK 9+ için JAX-B bağımlılıkları
uygulama "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
uygulama "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}
Bu bende işe yaradı:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.0</version>
</dependency>
Jasper'ın önerdiği gibi, tüm EclipseLink kütüphanesine bağlı kalmamak için, sadece EclipseLink MOXy'ye de bağlı kalabilirsiniz:
Maven
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>2.7.3</version>
</dependency>
Gradle
compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.moxy', version: '2.7.3'
Java 8 uygulamam için bağımlılıklar olarak, ek argüman olmadan hem JRE 8 hem de JRE 9 tarafından çalıştırılabilen bir *.jar üretir.
Ayrıca, JAXB API kullanılmadan önce bunun bir yerde çalıştırılması gerekir:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Geçici bir çözüm olarak şimdiye kadar harika çalışıyor. Yine de mükemmel bir çözüm gibi görünmüyor...
Derleme sırasında ve çalışma zamanında, --add-modules java.xml.bind
anahtarını ekleyin
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
JDK 9
modüllerinin iyi bir tanıtımı da şu adreste bulunabilir: