Pourquoi Java crie « NoClassDefFoundError: javax/xml/bind/JAXBException » et que faire en 2025 ?
\n\nAvez-vous déjà rencontré une situation où votre application Java, qui fonctionnait parfaitement hier, plante aujourd'hui avec l'erreur inquiétante java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException ? Si oui, vous n'êtes pas seul. Cette question a recueilli des milliers de vues sur Stack Overflow, et la demande de solution ne faiblit pas même en 2025. Le problème est lié à des changements fondamentaux dans l'écosystème Java, survenus il y a plusieurs années, mais qui continuent de causer des soucis aux développeurs.
Dans cet article, nous ne vous donnerons pas simplement « le poisson » — nous allons comprendre pourquoi cette erreur se produit et vous montrer trois méthodes fiables pour la corriger. Vous apprendrez à configurer correctement Maven, Gradle ou les arguments JVM pour que votre application fonctionne à nouveau. C'est parti !
\n\nLa racine du mal : Java 9 et le système modulaire
\n\nTout a commencé avec Java 9 (sorti en 2017). Dans cette version, Oracle a introduit le système modulaire (Project Jigsaw). De nombreux packages qui faisaient auparavant partie de la bibliothèque standard (JDK) ont été déplacés vers des modules séparés ou complètement supprimés. L'un de ces « exclus » était le package javax.xml.bind (JAXB — Java Architecture for XML Binding).
Sous Java 8 et versions antérieures, JAXB était disponible « prêt à l'emploi ». À partir de Java 9, il est devenu optionnel. Et dans Java 11, il a été complètement supprimé du JDK. Si vous écrivez du code qui utilise javax.xml.bind.JAXBContext, JAXBException ou Marshaller, et que vous l'exécutez sur Java 11+, vous obtiendrez inévitablement une NoClassDefFoundError.
Important : NoClassDefFoundError diffère de ClassNotFoundException. La première se produit lorsqu'une classe était disponible au moment de la compilation, mais a disparu lors de l'exécution. La seconde se produit lorsque la classe n'est pas trouvée du tout.
Scénario : à quoi ressemble le problème en pratique
\n\nImaginez que vous ayez une classe simple pour travailler avec XML :
\n\nimport javax.xml.bind.JAXBContext;\nimport javax.xml.bind.JAXBException;\nimport javax.xml.bind.Marshaller;\n\npublic class XmlProcessor {\n\n public void convertToXml(Object obj) throws JAXBException {\n JAXBContext context = JAXBContext.newInstance(obj.getClass());\n Marshaller marshaller = context.createMarshaller();\n marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);\n // ... logique de sortie\n }\n}\n\nVous compilez ce code sous Java 8 — tout va bien. Ensuite, vous mettez à jour votre JDK vers la version 11 ou 17, vous lancez l'application et vous voyez :
\n\nException in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException\n at XmlProcessor.convertToXml(XmlProcessor.java:6)\n ...\n\nÇa vous dit quelque chose ? Maintenant, passons à la résolution.
\n\nMéthode 1 : Ajouter JAXB API comme dépendance externe (recommandée)
\n\nL'approche la plus correcte et moderne est d'indiquer explicitement que votre application utilise JAXB. Pour cela, vous devez ajouter la bibliothèque via un système de build (Maven ou Gradle).
\n\nPour Maven (pom.xml)
\n\nAjoutez dans <dependencies> :
<dependency>\n <groupId>jakarta.xml.bind</groupId>\n <artifactId>jakarta.xml.bind-api</artifactId>\n <version>4.0.2</version>\n</dependency>\n<dependency>\n <groupId>org.glassfish.jaxb</groupId>\n <artifactId>jaxb-runtime</artifactId>\n <version>4.0.5</version>\n <scope>runtime</scope>\n</dependency>\n\nNotez qu'avec Jakarta EE 9 (juin 2021), le package javax.xml.bind a été renommé en jakarta.xml.bind. Si votre code est ancien et utilise javax.*, vous pouvez toujours utiliser