Minulla on koodia, joka käyttää JAXB API -luokkia, jotka on toimitettu osana JDK:ta Java 6/7/8:ssa. Kun suoritan saman koodin Java 9:llä, saan ajonaikana virheitä, jotka ilmoittavat, että JAXB-luokkia ei löydy.
JAXB-luokkia on tarjottu osana JDK:ta Java 6:sta lähtien, joten miksi Java 9 ei enää löydä näitä luokkia?
JAXB-rajapintoja pidetään Java EE:n rajapintoina, joten ne eivät enää sisälly oletusluokkapolkuun Java SE 9:ssä. Java 11:ssä ne on poistettu kokonaan JDK:sta.
Java 9:ssä otetaan käyttöön moduulien käsitteet, ja oletusarvoisesti luokkapolulla (tai pikemminkin moduulipolulla) on saatavilla java.se
-aggregaattimoduuli. Kuten nimestä voi päätellä, java.se
-aggregaattimoduuli ei sisällä Java EE -rajapintoja, jotka on perinteisesti liitetty Java 6/7/8:een.
Onneksi nämä JDK 6/7/8:ssa tarjotut Java EE API:t ovat edelleen JDK:ssa, mutta ne eivät vain ole oletusarvoisesti luokkapolulla. Ylimääräiset Java EE API:t ovat seuraavissa moduuleissa:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Nopea ja likainen ratkaisu: (vain JDK 9/10)
Jotta JAXB-API:t olisivat käytettävissä ajonaikana, määritä seuraava komentorivioptio:
----add-modules java.xml.bind
Mutta tämän täytyy silti toimia Java 8:n kanssa!!!
Jos yrität määrittää --add-modules
vanhemmalla JDK:lla, se räjähtää, koska se on tunnistamaton vaihtoehto. Ehdotan yhtä kahdesta vaihtoehdosta:
JDK_JAVA_OPTIONS
-ympäristömuuttujaa. Tämä ympäristömuuttuja luetaan automaattisesti java
-käynnistysohjelmalla Java 9+:lle.-XX:+IgnoreUnrecognizedVMOptions
, jotta JVM jättää tunnistamattomat vaihtoehdot äänettömästi huomiotta sen sijaan, että se räjähtäisi. Mutta varo! Kaikki muut käyttämäsi komentorivin argsit eivät enää ole JVM:n validoimia puolestasi. Tämä vaihtoehto toimii sekä Oraclen/OpenJDK:n että IBM:n JDK:n kanssa (JDK 8sr4:stä lähtien).Vaihtoehtoinen nopea ratkaisu: (vain JDK 9/10)
Huomaa, että voit asettaa kaikki edellä mainitut Java EE -moduulit saataville ajon aikana määrittämällä --add-modules java.se.ee
-vaihtoehdon. java.se.ee
-moduuli on yhdistelmämoduuli, joka sisältää java.se.ee
sekä edellä mainitut Java EE API -moduulit. Huomaa, että tämä ei toimi Java 11:ssä, koska java.se.ee
poistettiin Java 11:stä.
Perusteellinen pitkän aikavälin ratkaisu: (JDK 9 ja sen jälkeen)
Yllä luetellut Java EE API -moduulit on kaikki merkitty @Deprecated(forRemoval=true)
, koska ne on suunniteltu poistettavaksi Java 11:ssä. Joten --add-module
-lähestymistapa ei enää toimi Java 11:ssä suoraan laatikosta.
Java 11:ssä ja siitä eteenpäin sinun on lisättävä oma kopiosi Java EE:n API:ista luokka- tai moduulipolkuun. Voit esimerkiksi lisätä JAX-B API:t maven-riippuvuutena seuraavasti:
<!-- 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>
Katso lisätietoja JAXB:stä JAXB Reference Implementation page.
Täydelliset tiedot Javan modulaarisuudesta löydät JEP 261: Moduulijärjestelmä.
Gradle- tai Android Studio -kehittäjälle: (JDK 9 ja uudemmat)
Lisää seuraavat riippuvuudet build.gradle-tiedostoon:
dependencies {
// JAX-B-riippuvuudet JDK 9+:lle.
toteutus "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
toteutus "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}
Tämä toimi minulle:
<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>
Kuten @Jasper ehdotti, voit olla riippuvainen koko EclipseLink-kirjastosta, jos haluat välttää riippuvuuden koko EclipseLink-kirjastosta, voit myös olla riippuvainen vain EclipseLink MOXysta:
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'
Riippuvuuksina Java 8 -sovelluksessani, joka tuottaa *.jar-tiedoston, joka voidaan ajaa sekä JRE 8:lla että JRE 9:llä ilman lisäargumentteja.
Lisäksi tämä on suoritettava jossakin ennen JAXB API:n käyttöä:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Toimii toistaiseksi loistavasti, kiertotapana. Ei kuitenkaan näytä täydelliseltä ratkaisulta...
Sekä kääntämisen että ajon aikana lisää kytkin --add-modules java.xml.bind
.
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
Hyvä esittely JDK 9
moduuleista löytyy myös osoitteesta :