How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9?
I have code that uses JAXB API classes, which were included in the JDK from Java 6 through Java 8. When I run the same code with Java 9, I encounter runtime errors indicating that JAXB classes cannot be found.
Since JAXB classes were part of the JDK since Java 6, why can Java 9 no longer locate these classes, and how can I resolve this issue?
The java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9 occurs because JAXB (Java Architecture for XML Binding) was deprecated in Java 9 and completely removed from Java 11 and later versions as part of Java EE’s migration to the Jakarta EE project. To resolve this issue, you can either use the --add-modules java.xml.bind command line flag to explicitly include the JAXB module, or add JAXB dependencies manually to your project configuration.
Contents
- Understanding the Problem: Why JAXB is Missing in Java 9
- Command Line Solutions
- Project Configuration Solutions
- Migration Considerations
- Practical Implementation Examples
Understanding the Problem: Why JAXB is Missing in Java 9
In Java 8 and earlier versions, JAXB was included as part of the standard Java Development Kit (JDK). However, with the introduction of Java 9’s module system (Project Jigsaw), Oracle began the process of removing Java EE APIs from the JDK to make it more modular.
According to the official documentation, the
java.xml.bindmodule defines the Java Architecture for XML Binding (JAXB) API and is considered “upgradeable” but was deprecated starting from Java 9.
The key reasons for this change include:
- Modularity: Making the JDK more modular by removing optional APIs
- Standardization: Moving Java EE specifications to the Jakarta EE project under the Eclipse Foundation
- Reduced footprint: Creating a smaller, more focused JDK for different use cases
This means that code that worked seamlessly in Java 8 will fail in Java 9+ because the javax.xml.bind package is no longer available in the default classpath.
Command Line Solutions
Using --add-modules Flag
The quickest way to make JAXB available to your application is to use the --add-modules command line argument when running your Java application:
java --add-modules java.xml.bind -jar your-application.jar
For compilation, you can also specify this during the build process:
javac --add-modules java.xml.bind YourClass.java
JVM Arguments for Gradle/Maven Projects
When building with Gradle or Maven, you can add these JVM arguments to your build configuration:
For Gradle:
applicationDefaultJvmArgs = ["--add-modules", "java.xml.bind"]
For Maven:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--add-modules java.xml.bind</argLine>
</configuration>
</plugin>
Important Note: As mentioned in the Baeldung article, while the
--add-modulesapproach works quickly, it might not be the best long-term solution because it’s essentially a workaround for the module system changes.
Project Configuration Solutions
Adding JAXB Dependencies to Maven
For a more permanent solution, you can add the JAXB API and implementation dependencies to your pom.xml file:
<dependencies>
<!-- JAXB API -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- JAXB Implementation -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
<!-- For JDK 9+ compatibility, you might also need -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
Adding JAXB Dependencies to Gradle
For Gradle projects, add these dependencies to your build.gradle file:
dependencies {
implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.1'
implementation 'javax.activation:javax.activation-api:1.2.0'
}
IDE Configuration
If you’re using an IDE like IntelliJ IDEA or Eclipse, you might need to:
- Update your project structure to use the new dependencies
- Rebuild your project to ensure all dependencies are properly resolved
- Verify that the JAXB classes are now available in your classpath
Migration Considerations
Long-term Migration Strategy
While temporary fixes like --add-modules work, consider these long-term strategies:
-
Jakarta EE Migration: For Java 11 and later, migrate from
javax.xml.bindtojakarta.xml.bindas part of the Jakarta EE project. -
Alternative Libraries: Consider using modern XML processing libraries like:
- Jackson XML module
- XStream
- Woodstox
-
Dependency Management: Ensure your build tools are configured to handle the JAXB dependencies properly across different Java versions.
Java Version Compatibility
Here’s a compatibility reference:
| Java Version | JAXB Status | Recommended Solution |
|---|---|---|
| Java 6-8 | Included | No changes needed |
| Java 9 | Deprecated | --add-modules or manual dependencies |
| Java 10 | Deprecated | --add-modules or manual dependencies |
| Java 11+ | Removed | Manual dependencies or Jakarta EE migration |
Practical Implementation Examples
Basic JAXB Usage Example
Here’s a simple example demonstrating JAXB usage that would work after applying the fixes:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class ExampleObject {
private String name;
private int value;
// Getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
public static void main(String[] args) {
try {
// This will work after applying the JAXB fixes
JAXBContext context = JAXBContext.newInstance(ExampleObject.class);
System.out.println("JAXBContext created successfully!");
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Running with Java 9
To run this example with Java 9, you can use:
# Option 1: Using --add-modules
java --add-modules java.xml.bind --module-path your-dependency-path -cp . ExampleObject
# Option 2: With JAR file containing JAXB dependencies
java -cp "your-app.jar:jaxb-api.jar:jaxb-runtime.jar:" ExampleObject
Maven Project Setup Example
Here’s a complete Maven project structure that resolves the JAXB issue:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jaxb-java9-example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>9</maven.compiler.source>
<maven.compiler.target>9</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>9</source>
<target>9</target>
<compilerArgs>
<arg>--add-modules</arg>
<arg>java.xml.bind</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Sources
- Stack Overflow - How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- Baeldung - Handling NoClassDefFoundError for JAXBException in Java
- Mkyong.com - java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- CodeJava.net - [Solved] java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- GeeksforGeeks - How to Resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- Mastertheboss - How to solve java.lang.NoClassDefFoundError: javax/xml/bind Classes
- ConcretePage - [SOLVED-JAVA 9] Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- Oracle Documentation - java.xml.bind (Java SE 9 & JDK 9)
- LogicBig - Java 9 Modules - The Root Modules
- Jesper de Jong - JAXB on Java 9, 10, 11 and beyond
Conclusion
The java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9 is a common issue caused by Oracle’s decision to remove Java EE APIs from the JDK starting with Java 9. To resolve this problem:
- For quick fixes: Use the
--add-modules java.xml.bindcommand line flag when running or compiling your application - For permanent solutions: Add JAXB dependencies manually to your Maven or Gradle project configuration
- For long-term planning: Consider migrating to Jakarta EE APIs or alternative XML processing libraries
The key takeaway is that while the change was disruptive, it’s manageable with proper dependency management and understanding of the Java module system. Always test your application with the target Java version and ensure all required dependencies are properly configured in your build system.