Omgaan met NoClassDefFoundError voor JAXBException in Java 9

1. Inleiding

Voor iedereen die heeft geprobeerd te upgraden naar Java 9, hebben ze waarschijnlijk een soort van NoClassDefFoundError bij het compileren van code die eerder werkte in eerdere versies van Java.

In dit artikel kijken we naar een veelvoorkomende ontbrekende klasse, JAXBException, en verschillende manieren waarop we het kunnen oplossen. De hier geboden oplossingen zijn over het algemeen van toepassing op elke klasse die mogelijk ontbreekt bij het upgraden naar Java 9.

2. Waarom Java 9 niet kan vinden JAXBException?

Een van de meest besproken kenmerken van Java 9 is het modulesysteem. Het doel van het Java 9-modulesysteem is om de JVM-kernklassen en gerelateerde projecten op te splitsen in zelfstandige modules. Dit helpt ons applicaties te maken met een kleinere footprint door alleen de minimaal vereiste klassen op te nemen om uit te voeren.

Het nadeel is dat veel klassen niet meer standaard beschikbaar zijn op het klassenpad. In dit geval de class JAXBExceptionis te vinden in een van de nieuwe Jakarta EE-modules met de naam java.xml.bind. Omdat deze module niet vereist is voor de core Java-runtime, is deze niet standaard beschikbaar op het klassenpad.

Proberen een applicatie uit te voeren die gebruikmaakt van JAXBExceptionzal resulteren in:

NoClassDefFoundError: javax / xml / bind / JAXBException

Om dit te omzeilen we moeten de java.xml.bindmodule. Zoals we hieronder zullen zien, zijn er meerdere manieren om dit te bereiken.

3. Oplossing op korte termijn

De snelste manier om ervoor te zorgen dat de JAXB API-klassen beschikbaar zijn voor een toepassing, is door gebruik de –Add-modules opdrachtregelargument:

--add-modules java.xml.bind

Dit is echter om een ​​aantal redenen misschien geen goede oplossing.

Eerst de –Add-modules argument is ook nieuw in Java 9. Voor applicaties die op meerdere versies van Java moeten draaien, levert dit een aantal uitdagingen op. We zouden meerdere sets buildbestanden moeten onderhouden, één voor elke Java-versie waarop de applicatie draait.

Om dit te omzeilen kunnen we ook de -XX: + IgnoreUnrecognizedVMOptionsopdrachtregelargument voor oudere Java-compilers.

Dit betekent echter dat typefouten of verkeerd gespelde argumenten niet onder onze aandacht worden gebracht. Als we bijvoorbeeld proberen een minimale of maximale heapgrootte in te stellen en de argumentnaam verkeerd typen, krijgen we geen waarschuwing. Onze applicatie zal nog steeds starten, maar zal draaien met een andere configuratie dan we verwachten.

Ten tweede, de –Add-modules optie zal worden afgeschaft in een toekomstige Java-release. Dit betekent dat we op een gegeven moment nadat we een upgrade naar een nieuwe versie van Java hebben uitgevoerd, hetzelfde probleem zullen tegenkomen als het gebruik van een onbekend opdrachtregelargument en het probleem opnieuw moeten aanpakken.

4. Lange termijn oplossing

Er is een betere aanpak die in verschillende versies van Java werkt en niet zal breken met toekomstige releases.

De oplossing is om gebruik een hulpprogramma voor afhankelijkheidsbeheer, zoals Maven. Met deze aanpak zouden we de JAXB API-bibliotheek als een afhankelijkheid toevoegen, net als elke andere bibliotheek:

 javax.xml.bind jaxb-api 2.3.0 

De bovenstaande bibliotheek bevat alleen de JAXB API-klassen, waaronder JAXBException. Afhankelijk van de toepassing moeten we mogelijk andere modules toevoegen.

Houd er ook rekening mee dat de De namen van Maven-artefacten kunnen verschillen van de naam van de Java 9-module, zoals het geval is voor JAXB API. Het is te vinden op Maven Central.

5. Conclusie

Het Java 9-modulesysteem biedt een aantal voordelen, zoals een kleinere toepassingsgrootte en betere prestaties.

Het introduceert echter ook enkele onbedoelde gevolgen. Bij het upgraden naar Java 9 is het belangrijk om te begrijpen welke modules een applicatie echt nodig heeft en stappen te ondernemen om ervoor te zorgen dat ze beschikbaar zijn op het klassenpad.