Turiu tam tikrą kodą, kuriame naudojamos JAXB API klasės, pateiktos kaip "Java 6/7/8" JDK dalis. Kai paleidžiu tą patį kodą su "Java 9", paleidimo metu gaunamos klaidos, rodančios, kad JAXB klasių negalima rasti.
JAXB klasės kaip JDK dalis teikiamos nuo "Java 6", tad kodėl "Java 9" nebegali rasti šių klasių?
JAXB API laikomos "Java EE" API, todėl "Java SE 9" jos nebėra numatytojo klasių kelio sąraše. "Java 11" jos visiškai pašalintos iš JDK.
Java 9 įvestos modulių sąvokos, ir pagal nutylėjimą klasės kelyje (tiksliau, modulių kelyje) yra java.se
suvestinis modulis. Kaip matyti iš pavadinimo, java.se
agreguotasis modulis neapima Java EE API, kurios tradiciškai buvo pridedamos prie Java 6/7/8.
Laimei, šios Java EE API, kurios buvo pateiktos JDK 6/7/8, vis dar yra JDK, bet jų tiesiog'nėra klasių kelyje pagal nutylėjimą. Papildomos "Java EE" API pateikiamos šiuose moduliuose:
java.activation
java.corba
java.transaction
java.xml.bind << This one contains the JAXB APIs
java.xml.ws
java.xml.ws.annotation
Skubus ir paprastas sprendimas: (tik JDK 9/10)
Norėdami, kad JAXB API būtų prieinamos paleidimo metu, nurodykite šią komandinės eilutės parinktį:
--add-modules java.xml.bind
Bet man vis tiek reikia, kad tai veiktų su "Java 8"!!!
Jei bandysite nurodyti --add-modules
su senesne JDK versija, ji suges, nes tai neatpažįstama parinktis. Siūlau vieną iš dviejų variantų:
JDK_JAVA_OPTIONS
. Šį aplinkos kintamąjį [automatiškai perskaito][1] java
paleidimo programa, skirta "Java 9+".-XX:+IgnoreUnrecognizedVMOptions
, kad JVM tyliai ignoruotų neatpažintas parinktis, užuot sprogdinęs. Tačiau saugokitės! Bet kokių kitų jūsų naudojamų komandinės eilutės argumentų JVM jums nebepatvirtins. Ši parinktis veikia su Oracle/OpenJDK ir IBM JDK (nuo JDK 8sr4).Antrinis greitas sprendimas: (tik JDK 9/10)
Atkreipkite dėmesį, kad visus pirmiau minėtus "Java EE" modulius galite padaryti prieinamus paleidimo metu nurodydami --add-modules java.se.ee
parinktį. Modulis java.se.ee
yra jungtinis modulis, į kurį įeina java.se.ee
ir pirmiau minėti Java EE API moduliai. Atkreipkite dėmesį, kad tai neveikia "Java 11", nes java.se.ee
buvo pašalintas iš "Java 11".
Tinkamas ilgalaikis sprendimas: (JDK 9 ir vėlesnės versijos)
Visi pirmiau išvardyti "Java EE API" moduliai pažymėti @Deprecated(forRemoval=true)
, nes juos [planuojama pašalinti][2] [Java 11][3]. Taigi --add-module
metodas nebeveiks "Java 11" iš karto.
Tai, ką turėsite daryti "Java 11" ir vėlesnėse versijose, tai įtraukti savo "Java EE" API kopiją į klasės kelią arba modulio kelią. Pavyzdžiui, galite pridėti JAX-B API kaip "maven" priklausomybę taip:
<!-- 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>
Daugiau informacijos apie JAXB rasite JAXB nuorodų įgyvendinimo puslapyje.
Išsamios informacijos apie "Java" modulinę sistemą rasite [JEP 261: Modulių sistema][4].
Dėl "Gradle" arba "Android Studio" kūrėjo: (JDK 9 ir vėlesnės versijos).
Į savo build.gradle failą įtraukite šias priklausomybes:
priklausomybės {
// JAX-B priklausomybės JDK 9+
implementation "jakarta.xml.bind:jakarta.xml.bind-api:2.3.2"
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.2"
}
```
[1]: https://www.oracle.com/technetwork/java/javase/9-new-features-3745613.html#JDK-8170832
[2]: http://openjdk.java.net/jeps/320
[3]: http://openjdk.java.net/projects/jdk/11/
[4]: http://openjdk.java.net/jeps/261
[5]: https://stackoverflow.com/a/46455026/3763032
Man tai padėjo:
<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>
Kaip siūlė @Jasper, kad nereikėtų priklausyti nuo visos "EclipseLink" bibliotekos, taip pat galite priklausyti tik nuo "EclipseLink MOXy":
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'
Kaip priklausomybės mano "Java 8" programai, kuri sukuria *.jar, kurį galima paleisti tiek su JRE 8, tiek su JRE 9 be jokių papildomų argumentų.
Be to, prieš pradedant naudoti JAXB API, ją reikia kažkur paleisti:
System.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
Kol kas veikia puikiai, kaip apeinamasis variantas. Tačiau tai neatrodo tobulas sprendimas...
Kompiliavimo ir vykdymo metu pridėkite jungiklį --add-modules java.xml.bind
javac --add-modules java.xml.bind <java file name>
java --add-modules java.xml.bind <class file>
Gerą JDK 9
modulių įvadą taip pat galima rasti adresu :