Håndtering af NoClassDefFoundError til JAXBException i Java 9

1. Introduktion

For alle, der har forsøgt at opgradere til Java 9, har de sandsynligvis oplevet en slags NoClassDefFoundError ved kompilering af kode, der tidligere fungerede i tidligere versioner af Java.

I denne artikel ser vi på en almindelig manglende klasse, JAXBE undtagelseog forskellige måder, vi kan løse det på. Løsningerne, der leveres her, gælder generelt for enhver klasse, der mangler, når du opgraderer til Java 9.

2. Hvorfor Java 9 ikke kan finde JAXBE undtagelse?

En af de mest diskuterede funktioner i Java 9 er modulsystemet. Målet med Java 9-modulsystemet er at opdele de centrale JVM-klasser og relaterede projekter i enkeltstående moduler. Dette hjælper os med at oprette applikationer med mindre fodaftryk ved kun at inkludere de mindst nødvendige klasser, der skal køres.

Ulempen er, at mange klasser som standard ikke længere er tilgængelige på klassestien. I dette tilfælde klassen JAXBE undtagelsefindes i et af de nye navngivne Jakarta EE-moduler java.xml.bind. Da dette modul ikke kræves af kernen i Java-runtime, er det ikke tilgængeligt på klassestien som standard.

Forsøger at køre et program, der bruger JAXBE undtagelsevil medføre:

NoClassDefFoundError: javax / xml / bind / JAXBException

At komme rundt om dette vi skal inkludere java.xml.bindmodul. Som vi vil se nedenfor, er der flere måder at opnå dette på.

3. Kortsigtet løsning

Den hurtigste måde at sikre sig, at JAXB API-klasser er tilgængelige for en applikation, er at tilføje brug –Add-moduler kommandolinjeargument:

--add-modules java.xml.bind

Dette kan dog ikke være en god løsning af et par årsager.

Først –Add-moduler argumentet er også nyt i Java 9. For applikationer, der skal køre på flere versioner af Java, giver dette nogle udfordringer. Vi bliver nødt til at vedligeholde flere sæt build-filer, en for hver Java-version, som applikationen kører på.

For at omgå dette kunne vi også bruge -XX: + Ignorer ikke-genkendtVMOptionskommandolinjeargument for ældre Java-kompilatorer.

Dette betyder dog, at enhver skrivefejl eller forkert stavet argument ikke bliver gjort opmærksom på os. For eksempel, hvis vi forsøger at indstille en minimum eller maksimal bunke størrelse og fejlagtigt indtaste argumentets navn, får vi ikke en advarsel. Vores applikation starter stadig, men den kører med en anden konfiguration, end vi forventer.

For det andet, den –Add-moduler indstilling udfases i en fremtidig Java-udgivelse. Dette betyder på et eller andet tidspunkt, når vi opgraderer til en ny version af Java, vi står over for det samme problem med at bruge et ukendt kommandolinjeargument og er nødt til at løse problemet igen.

4. Langsigtet løsning

Der er en bedre tilgang, der fungerer på tværs af forskellige versioner af Java og ikke bryder med fremtidige udgivelser.

Løsningen er at bruge et afhængighedsstyringsværktøj som Maven. Med denne tilgang vil vi tilføje JAXB API-biblioteket som en afhængighed ligesom ethvert andet bibliotek:

 javax.xml.bind jaxb-api 2.3.0 

Ovenstående bibliotek indeholder kun JAXB API-klasser, som inkluderer JAXBE undtagelse. Afhængigt af applikationen skal vi muligvis medtage andre moduler.

Husk også, at Navne på Maven-artefakter kan være forskellige end navnet på Java 9-modulet, som det er tilfældet med JAXB API. Det kan findes på Maven Central.

5. Konklusion

Java 9-modulsystemet giver en række fordele såsom nedsat applikationsstørrelse og bedre ydeevne.

Imidlertid introducerer det også nogle utilsigtede konsekvenser. Når du opgraderer til Java 9, er det vigtigt at forstå, hvilke moduler en applikation virkelig kræver, og tage skridt til at sikre, at de er tilgængelige på klassestien.