Mam kod, który używa klas API JAXB, które zostały dostarczone jako część JDK w Javie 6/7/8. Gdy uruchamiam ten sam kod z Javą 9, w czasie wykonywania pojawiają się błędy wskazujące, że nie można znaleźć klas JAXB.
Klasy JAXB są dostarczane jako część JDK od Java 6, więc dlaczego Java 9 nie może już znaleźć tych klas?
Odpowiedzi:
Interfejsy API JAXB są uważane za interfejsy API Java EE i dlatego nie są już zawarte w domyślnej ścieżce klas w Java SE 9. W Javie 11 są one całkowicie usuwane z JDK.
Java 9 wprowadza koncepcje modułów i domyślnie
java.se
moduł agregujący jest dostępny na ścieżce klasy (a raczej ścieżce modułu). Jak sama nazwa wskazuje,java.se
moduł agregujący nie zawiera interfejsów API Java EE, które były tradycyjnie pakowane w Javę 6/7/8.Na szczęście te interfejsy API Java EE, które zostały udostępnione w JDK 6/7/8, nadal znajdują się w JDK, ale domyślnie nie znajdują się w ścieżce klas. Dodatkowe interfejsy API Java EE znajdują się w następujących modułach:
Szybkie i brudne rozwiązanie: (tylko JDK 9/10)
Aby interfejsy API JAXB były dostępne w czasie wykonywania, określ następującą opcję wiersza polecenia:
--add-modules java.xml.bind
Ale nadal potrzebuję tego do pracy z Javą 8 !!!
Jeśli spróbujesz podać
--add-modules
starszy JDK, zostanie on wysadzony, ponieważ jest to nierozpoznana opcja. Proponuję jedną z dwóch opcji:JDK_JAVA_OPTIONS
zmiennej środowiskowej. Ta zmienna środowiskowa jest automatycznie odczytywana przez programjava
uruchamiający dla Java 9+.-XX:+IgnoreUnrecognizedVMOptions
aby JVM dyskretnie ignorował nierozpoznane opcje, zamiast wysadzać w powietrze. Ale strzeż się! Wszelkie inne argumenty wiersza polecenia, których użyjesz, nie będą już dla ciebie sprawdzane przez JVM. Ta opcja działa z Oracle / OpenJDK oraz IBM JDK (od JDK 8sr4).Alternatywne szybkie rozwiązanie: (tylko JDK 9/10)
Pamiętaj, że możesz udostępnić wszystkie powyższe moduły Java EE w czasie wykonywania, określając tę
--add-modules java.se.ee
opcję.java.se.ee
Moduł jest modułem, który zawiera kruszywajava.se.ee
, jak również wyżej wymienionych modułów Java EE API. Uwaga: nie działa to w Javie 11, ponieważjava.se.ee
została usunięta w Javie 11.Właściwe rozwiązanie długoterminowe: (JDK 9 i nowsze)
Wszystkie wymienione wyżej moduły API Java EE są oznaczone,
@Deprecated(forRemoval=true)
ponieważ ich usunięcie zaplanowano w Javie 11 . Dlatego--add-module
podejście nie będzie już działać w Javie 11 od razu po wyjęciu z pudełka.W języku Java 11 i nowszych wersjach należy umieścić własną kopię interfejsów API Java EE na ścieżce klasy lub ścieżce modułu. Na przykład możesz dodać interfejsy API JAX-B jako zależność Maven, taką jak ta:
Patrz strona Reference Implementation JAXB więcej szczegółów na JAXB.
Aby uzyskać szczegółowe informacje na temat modułowości Java, zobacz JEP 261: Moduł systemu
Dla programistów Gradle lub Android Studio: (JDK 9 i nowsze wersje)
Dodaj następujące zależności do
build.gradle
pliku:źródło
javax.xml.bind
i inne zajęcia JavaEE są zaplanowane do usunięcia w Javie 11, za JEP-320 .java.se.ee
moduł został usunięty, więc--add-modules
rozwiązanie już nie działa. Zamiast tego użyj zalecanego rozwiązania: dodaj JAXB jako osobną zależność.W moim przypadku (słoik z grubym bootem) po prostu dodaję następujący tekst do pom.xml.
źródło
testCompile('javax.xml.bind:jaxb-api')
ode mnie.<scope>runtime</scope>
do takiego przypadkuŻadne z tych rozwiązań nie działało dla mnie dobrze w ostatnim JDK 9.0.1.
Odkryłem, że ta lista zależności jest wystarczająca do prawidłowego funkcjonowania, więc nie trzeba jawnie określać
--add-module
(chociaż jest ona określona w pom pom tych zależności). Wystarczy tylko podać tę listę zależności:źródło
pom.xml
plik konfiguracji Maven. Jeśli nie wiesz, co to jest, lepiej zacząć od początku<dependency> <groupId>javax.activation</groupId> <artifactId>javax.activation-api</artifactId> <version>1.2.0</version> </dependency>
jako ostatniej zależności.To działało dla mnie:
Aktualizacja
Jak sugerował @Jasper, aby uniknąć zależności od całej biblioteki EclipseLink, możesz także polegać na EclipseLink MOXy:
Maven
Gradle
Jako zależności dla mojej aplikacji Java 8, która tworzy plik * .jar, który może być uruchamiany zarówno przez JRE 8, jak i JRE 9 bez dodatkowych argumentów.
Ponadto należy to gdzieś wykonać, zanim zostanie użyty interfejs API JAXB:
Jak dotąd działa świetnie jako obejście. Nie wygląda to jednak na idealne rozwiązanie ...
źródło
org.eclipse.persistence:eclipselink
tylko w celu uzyskania interfejsów API JAXB jest bardzo ciężką zależnością, chyba że już używasz eclipselink?-XX:+IgnoreUnrecognizedVMOptions
opcji wiersza poleceń (zaktualizowałem moją odpowiedź o szczegóły)org.eclipse.persistence
, artefactIdorg.eclipse.persistence.moxy
.czyste rozwiązanie dla wszystkich JDK> = 9
Musisz dodać dwie zależności do swojej kompilacji
Jako implementację postanowiłem użyć implementacji referencyjnej przez glassfish, aby pozbyć się starych klas / bibliotek com.sun. W rezultacie dodałem w swojej wersji maven
Zauważ, że od wersji 2.3.1 nie musisz już dodawać javax.activation. (patrz https://github.com/eclipse-ee4j/jaxb-ri/issues/1222 )
źródło
to dlatego, że wersja Java, jeśli używasz jdk 9 lub nowszej wersji, po prostu dodaj to do pom
źródło
Aby rozwiązać ten problem, zaimportowałem niektóre pliki JAR w moim projekcie:
http://search.maven.org/remotecontent?filepath=com/sun/activation/javax.activation/1.2.0/javax.activation-1.2.0.jar
http://search.maven.org/remotecontent?filepath=javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-core/2.3.0/jaxb-core-2.3.0.jar
http://search.maven.org/remotecontent?filepath=com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar
źródło
com.sun.xml.bind
artefakty są stare i zostały dostarczone wyłącznie w celu zachowania zgodności wstecznej. Zamiast tego należy użyć równoważnychorg.glassfish.jaxb
artefaktów, jak wspomniano w niektórych innych odpowiedziach.W momencie kompilacji, a także w czasie wykonywania, dodaj przełącznik
--add-modules java.xml.bind
Dobre wprowadzenie
JDK 9
modułów można również znaleźć na stronie : https://www.youtube.com/watch?v=KZfbRuvv5qcźródło
To zadziałało dla mnie. Dodanie tylko jaxb-api nie wystarczyło.
źródło
com.sun.xml.bind
artefakty są stare i zostały dostarczone wyłącznie w celu zachowania zgodności wstecznej. Zamiast tego należy użyć równoważnychorg.glassfish.jaxb
artefaktów, jak wspomniano w niektórych innych odpowiedziach.Przejdź do swojego Build.gradle i dodaj poniższe zależności dla Java 9 lub Java 10.
źródło
Możesz użyć
--add-modules=java.xml.bind
Opcji JVM aby dodać moduł powiązania xml do środowiska wykonawczego JVM.Na przykład:
java --add-modules=java.xml.bind XmlTestClass
źródło
Aktualizacja kwietnia 2019 r
Changelong dla wydań JAXB jest na https://javaee.github.io/jaxb-v2/doc/user-guide/ch02.html
fragmenty:
Autorytatywny link znajduje się na https://github.com/eclipse-ee4j/jaxb-ri#maven-artifacts
org.glassfish.jaxb: jaxb-runtime: jar: 2.3.2 wciąga:
Oryginalna odpowiedź
Po jakich artefaktach powinienem użyć JAXB RI w moim projekcie Maven? w Maven możesz użyć profilu takiego jak:
Drzewo zależności pokazuje:
Aby użyć tego w Eclipse, powiedz Oxygen.3a Release (4.7.3a) lub nowszy, Ctrl-Alt-P, lub kliknij prawym przyciskiem myszy projekt, Maven, a następnie wybierz profil.
źródło
javax.xml.bind
>jaxb-api
, którą widziałam gdzie indziej, jest w rzeczywistości zbędna. Ciągnie to zależność od ryb szklistych. Właśnie tego spróbowałem i rzeczywiście działa.W przypadku Java Web Start Execution możemy użyć sugestii Andy'ego Guiberta w następujący sposób:
Zwróć uwagę na dodatkowe „=” w --add-module. Zobacz ten bilet OpenJDK lub ostatnią uwagę w „Zrozumieniu ostrzeżeń dotyczących dostępu do środowiska wykonawczego” platformy Java, Standard Edition Oracle JDK 9 Migration Guide .
źródło
dodaj zależność javax.xml.bind w pom.xml
źródło
Ponieważ JavaEE jest teraz zarządzany przez https://jakarta.ee/ , nowe współrzędne Maven od 2.3.2 to:
https://eclipse-ee4j.github.io/jaxb-ri/#maven-artifacts
Pierwsza wydana wersja jaxb.version to 2.3.2.
źródło
Śledziłem ten adres URL i poniższe ustawienia naprawdę mi pomogły. Używam Java 10 z STS IDE w Macbook Pro. To działa jak urok.
źródło
To rozwiązało moje problemy z zależnościami uruchomionymi Apache Camel 2.24.1 na Javie 12:
źródło
Ten sam problem napotkałem podczas korzystania z Spring Boot
2.0.5.RELEASE
w Javie 11.Samo dodanie
javax.xml.bind:jaxb-api:2.3.0
nie rozwiązało problemu. Musiałem także zaktualizować Spring Boot do najnowszego Milestone2.1.0.M2
, więc zakładam, że zostanie to naprawione w następnej oficjalnej wersji.źródło
Musisz dodać zależności JAX-B podczas korzystania z JDK 9+. Dla Android Studio użytkownikiem, musisz dodać do swojej
build.gradle
„sdependencies {}
bloku:źródło
Natknąłem się również na wyjątek ClassNotFoundException: javax.xml.bind.DatatypeConverter przy użyciu Java 11 i
Próbowałem wszystkich tych rzeczy, dodając javax.xml.bind: jaxb-api lub spring boot jakarta.xml.bind-api .. Znalazłem wskazówkę dotyczącą poprawek w wersji jjwt 0.10.0 .. ale co najważniejsze, pakiet jjwt to teraz podzielone!
Dlatego sprawdź to odniesienie: https://github.com/jwtk/jjwt/issues/510
Po prostu, jeśli używasz
idź po
jjwt wersja 0.11.x, ale użyj podzielonych pakietów: https://github.com/jwtk/jjwt#install
Nie można znaleźć wyższej wersji dla zależności jjwt, ponieważ dzielą pakiety.
Twoje zdrowie.
źródło
Nie odpowiedź, ale dodatek: Dostałem, ponieważ uruchamianie
groovysh
(Groovy 2.4.13), jeśli JAVA_HOME wskazuje na instalację Java 9 (java version "9.0.1"
a konkretnie) kończy się fatalnie:Rozwiązaniem było:
Przejdź do projektu JAXB na github.io ( „JAXB jest licencjonowany na podstawie podwójnej licencji - CDDL 1.1 i GPL 2.0 z wyjątkiem ścieżki klasy” )
Pobieranie
jaxb-ri-2.3.0.zip
Rozpakuj, gdziekolwiek umieścisz pliki infrastruktury Java (w moim przypadku,
/usr/local/java/jaxb-ri/
). Inne rozwiązanie może istnieć (może przez SDKMAN, nie wiem)Upewnij się, że słoiki w podkatalogu lib znajdują się w
CLASSPATH
. Robię to za pomocą skryptu uruchomionego przy starcie basha, zwanego/etc/profile.d/java.sh
, w którym dodałem (między innymi wierszami) następującą pętlę:Pakowane w funkcję ...
I to działa!
źródło
Potrzebujesz tylko 1 zależności:
źródło
OK, miałem ten sam problem, ale używałem Java 8 i ciągle otrzymywałem ten błąd, wypróbowałem większość rozwiązań. ale okazuje się, że mój maven wciąż wskazuje Java 9, mimo że ustawiłem globalną wersję Java na 8, gdy tylko ustaliłem, że wszystko działa.
Dla każdego, kto może mieć tego rodzaju problem, sprawdź Jak naprawić Maven, aby używał domyślnej Java
źródło
Stara odpowiedź „Problem rozwiązany przez przejście na amazoncorretto” Odpowiedź na wiadomość: Użyłem najnowszej wersji corretto, ale jest podobny jdk 1.8. więc i tak potrzebujemy dodać zależności ręcznie
źródło
amazoncorretto:latest
obecnie daje JDK 8, a nie 11. Wiele obrazów Dockera nadal opiera się na JDK 8, właśnie z powodu problemów z kompatybilnością spowodowanych usunięciem interfejsu API między JDK 8 -> 11Wersje zależności, których musiałem użyć podczas kompilacji pod docelową wersję Java 8. Testowana aplikacja w środowiskach JRE Java 8, 11 i 12.
źródło
Dla mnie w Javie 11 i stopniach to się udało:
źródło
Musisz dodać zależności mavb do maven. Wersja implementacyjna glassfish 2.3.2 jest doskonale kompatybilna z nową wersją interfejsu API jakarta EE jaxb api 2.3.2.
źródło
miałem podobne problemy po uaktualnieniu mojego projektu do java 11, a następnie to, co naprawiłem, to uaktualnienie do wersji spring boot 2.1.1, która najwyraźniej obsługuje java 11, to pomogło
źródło
Wiem, że spóźniłem się na imprezę, ale mój błąd ostatecznie wymagał innego rozwiązania ... również bardzo prostego
Oryginalnie rozłożyłem się na Tomcat 9 i zdałem sobie sprawę, że potrzebuję 7 ... Zapomniałem zmapować ścieżkę swojej klasy z powrotem do wersji 7 w build.xml
Mam nadzieję, że naprawi to błąd w przyszłości, któremu uda się przeoczyć ten prosty problem, tak jak ja!
źródło
Jeśli wywołujesz usługi sieciowe SOAP (na przykład za pomocą
jaxws-maven-plugin
), dodając tę zależność, wszystkie błędy JAXB znikają:Testowane z Javą 13
źródło