Umgang mit NoClassDefFoundError für JAXBException in Java 9

Umgang mit NoClassDefFoundError für JAXBException in Java 9

1. Einführung

Für alle, die versucht haben, ein Upgrade auf Java 9 durchzuführen, ist beim Kompilieren von Code, der zuvor in früheren Java-Versionen funktioniert hat, wahrscheinlich eine ArtNoClassDefFoundError wied aufgetreten.

In diesem Artikel werden wir uns eine häufig fehlende Klasse,JAXBException, und verschiedene Möglichkeiten zur Lösung ansehen. Die hier bereitgestellten Lösungen gelten im Allgemeinen für alle Klassen, die beim Upgrade auf Java 9 fehlen.

2. Warum kann Java 9JAXBException nicht finden?

Eine der am häufigsten diskutierten Funktionen von Java 9 ist das Modulsystem. The goal of the Java 9 module system is to break apart the core JVM classes and related projects into stand-alone modules. Auf diese Weise können Sie Anwendungen mit geringerem Platzbedarf erstellen, indem Sie nur die für die Ausführung erforderlichen Mindestklassen einbeziehen.

Der Nachteil ist, dass viele Klassen standardmäßig nicht mehr im Klassenpfad verfügbar sind. In diesem Fall befindet sich der Scan der KlasseJAXBExceptionin einem der neuen Java EE-Module mit dem Namenjava.xml.bind. Da dieses Modul für die Java-Kernlaufzeit nicht erforderlich ist, ist es standardmäßig nicht im Klassenpfad verfügbar.

Der Versuch, eine Anwendung auszuführen, dieJAXBExceptionwill verwendet, führt zu:

NoClassDefFoundError: javax/xml/bind/JAXBException

Um diesewe must include the java.xml.bindmodule zu umgehen. Wie wir weiter unten sehen werden, gibt es mehrere Möglichkeiten, dies zu erreichen.

3. Eine kurzfristige Lösung

Der schnellste Weg, um sicherzustellen, dass die JAXB-API-Klassen für eine Anwendung verfügbar sind, besteht darin,use the –add-modules command line argument hinzuzufügen:

--add-modules java.xml.bind

Dies ist jedoch möglicherweise aus mehreren Gründen keine gute Lösung.

Erstens ist das–add-modules -Sargument auch in Java 9 neu. Für Anwendungen, die auf mehreren Java-Versionen ausgeführt werden müssen, ist dies mit einigen Herausforderungen verbunden. Wir müssten mehrere Sätze von Build-Dateien verwalten, einen für jede Java-Version, auf der die Anwendung ausgeführt wird.

Um dies zu umgehen, können wir auch das Befehlszeilenargument-XX:+IgnoreUnrecognizedVMOptionsfür ältere Java-Compiler verwenden.

Dies bedeutet jedoch, dass Tippfehler oder falsch geschriebene Argumente nicht auf uns aufmerksam gemacht werden. Wenn wir beispielsweise versuchen, eine minimale oder maximale Heap-Größe festzulegen und den Argumentnamen falsch einzugeben, wird keine Warnung angezeigt. Unsere Anwendung wird weiterhin gestartet, jedoch mit einer anderen Konfiguration als erwartet ausgeführt.

Zweitens wird die Option–add-modules in einer zukünftigen Java-Version nicht mehr unterstützt. Dies bedeutet, dass wir irgendwann nach dem Upgrade auf eine neue Java-Version das gleiche Problem haben, ein unbekanntes Befehlszeilenargument zu verwenden, und das Problem erneut beheben müssen.

4. Langfristige Lösung

Es gibt einen besseren Ansatz, der für verschiedene Versionen von Java funktioniert und nicht mit zukünftigen Versionen bricht.

Die Lösung ist zuutilize a dependency management tool such as Maven. Mit diesem Ansatz würden wir die JAXB-API-Bibliothek wie jede andere Bibliothek als Abhängigkeit hinzufügen:


    javax.xml.bind
    jaxb-api
    2.3.0

Die obige Bibliothek enthält nur die JAXB-API-Klassen, dieJAXBException enthalten. Abhängig von der Anwendung müssen wir möglicherweise andere Module einbinden.

Beachten Sie auch, dassMaven artifact names may be different than the Java 9 module name ist, wie dies bei der JAXB-API der Fall ist. Es kann aufMaven Central gefunden werden.

5. Fazit

Das Java 9-Modulsystem bietet eine Reihe von Vorteilen, wie z. B. die Verringerung der Anwendungsgröße und eine bessere Leistung.

Es bringt jedoch auch einige unbeabsichtigte Konsequenzen mit sich. Beim Upgrade auf Java 9 ist es wichtig zu wissen, welche Module eine Anwendung wirklich benötigt, und Maßnahmen zu ergreifen, um sicherzustellen, dass sie im Klassenpfad verfügbar sind.