Comment corriger l'erreur java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Comment corriger l'erreur java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException Dans Java SE 9 et 10, la classe JAXB n'est plus présente dans la variable "classpath" par défaut. A partir de la version 11, elle a complètement disparu de Java en édition standard. Comment faire ?

JAXB est une API fournissant au langage Java un ensemble d'outils pour faciliter la génération et la manipulation de fichiers XML. Si vous mettez à jour votre plateforme Java dans une version supérieure ou égale à la version 9, vous obtiendrez l'erreur suivante "java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException". Cette erreur signifie que la classe JAXB n'a pas été trouvée. Elle est due à la modification de la gestion de la classe par Java. Depuis la version 9, l'API JAXB est considérée comme API d'entreprise et est donc fournie avec Java EE. Pour les utilisateurs de Java SE version 9 et 10, la classe n'est plus présente dans la variable "classpath" par défaut mais les fichiers sont toujours présents. A partir de la version 11, l'API JAXB a complètement disparu de Java en édition standard.

Si vous êtes utilisateurs de Java 9 et 10, il existe des solutions pour récupérer ces classes puisqu'elles sont encore présentes dans les fichiers. Quand vous lancez votre programme, vous pouvez préciser l'argument "--add-modules" qui permet d'inclure un module supplémentaire avant de lancer un programme. Il faut alors indiquer le module "java.xml.bind", qui contient JAXB :

--add-modules java.xml.bind

Il existe plusieurs modules qui comme JAXB ne sont plus inclus dans le chemin des classes par défaut. Si vous avez besoin de plusieurs de ces classes, alors il faut que vous ajoutiez plutôt le module "java.se.ee" qui permet d'inclure toutes les API Java EE encore installées.

--add-modules java.se.ee

Cette solution empêchera par contre une rétrocompatibilité avec Java 8 et les versions antérieures, qui ne connaissent pas l'option "--add-modules". Vous pouvez corriger ce point soit en développant un script de lancement qui va vérifier la version de Java grâce à la variable "$JAVA_HOME/release" et ajouter l'argument si besoin. Vous pouvez également utiliser l'argument "-XX:+IgnoreUnrecognizedVMOptions" qui va indiquer à la JVM de ne plus valider les arguments avant de lancer la commande. En revanche, plus aucun argument ne sera validé et cela peut être problématique pour détecter une erreur d'écriture.

Il existe également une solution plus propre et surtout compatible avec la version 11 de Java et au-delà. En effet, à partir de cette version, l'API JAXB n'est plus du tout incluse. Il faut donc faire appel à un système de gestion de production de projet Java, Maven par exemple. Vous pouvez alors inclure vos propres copies des modules de Java EE en tant que dépendance du projet.

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

Java