Question
How to Fix javax.xml.bind.JAXBException NoClassDefFoundError in Java 9+
Question
I have code that uses JAXB API classes, and those classes were included with the JDK in Java 6, 7, and 8. When I run the same code on Java 9, I get runtime errors saying that JAXB classes cannot be found.
For example, code like this may compile or work on Java 8:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
public class Main {
public static void main(String[] args) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(Person.class);
System.out.println(context);
}
}
class Person {
public String name;
}
Why does Java 9 no longer find javax.xml.bind.JAXBException and other JAXB classes even though JAXB was part of earlier JDK versions? How can this be resolved?
Short Answer
By the end of this page, you will understand why JAXB worked automatically in Java 8 but fails in Java 9 and later, what changed in the JDK module system, and how to fix the problem by adding the right module or external dependencies.
Concept
JAXB stands for Java Architecture for XML Binding. It lets Java programs convert objects to XML and XML back to objects.
In Java 6, 7, and 8, JAXB APIs such as javax.xml.bind.JAXBContext and javax.xml.bind.JAXBException were bundled with the JDK. That meant many programs could use JAXB without adding anything extra.
Starting with Java 9, Java introduced the module system. Some APIs that were previously available by default were moved into named modules that were not always loaded automatically. JAXB was placed in the java.xml.bind module.
This created an important difference:
- Java 8 and earlier: JAXB was on the classpath by default.
- Java 9: JAXB existed, but was not necessarily available unless you explicitly added the module.
- Java 11 and later: JAXB was removed from the JDK entirely, so you must add it as an external dependency.
That is why code that worked in Java 8 can fail with errors like:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
This error means the class was expected at runtime, but the JVM could not load it.
Why this matters in real programming:
- Upgrading Java versions can break code even when your source code has not changed.
- Some libraries depend on JAXB indirectly, so you may see this error even if your own code does not import JAXB directly.
- Understanding the difference between JDK-provided APIs and application dependencies is essential for maintaining Java projects.
Mental Model
Think of the JDK like a large building.
- In Java 8, JAXB was in a room that was already open, so your program could walk in and use it.
- In Java 9, that room was moved behind a door with a label. You now have to explicitly ask for access to that module.
- In Java 11+, the room is no longer in the building at all. If you need it, you must bring it yourself.
So the problem is not that your code suddenly became wrong. The environment around your code changed.
Syntax and Examples
In practice, the fix depends on your Java version.
1. Java 9 or Java 10: add the JAXB module
If you are running on Java 9 or 10, JAXB is still present in the JDK but not always included by default.
Run your application with:
java --add-modules java.xml.bind Main
If compiling manually:
javac --add-modules java.xml.bind Main.java
java --add-modules java.xml.bind Main
If you use a module-info.java, add:
module my.app {
requires java.xml.bind;
}
2. Java 11 and later: add JAXB dependencies
From Java 11 onward, JAXB is no longer part of the JDK. You must add dependencies yourself.
Maven example
<dependencies>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
org.glassfish.jaxb
jaxb-runtime
2.3.3
Step by Step Execution
Consider this code:
import javax.xml.bind.JAXBContext;
public class Main {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Person.class);
System.out.println("Created: " + context);
}
}
class Person {
public String name;
}
Here is what happens step by step:
- The JVM starts
Main.main(). - The line
JAXBContext.newInstance(Person.class)is executed. - The JVM tries to load the
JAXBContextclass. JAXBContextdepends on JAXB classes such asJAXBExceptionand an implementation.- If those classes are not available in the runtime environment, class loading fails.
- The JVM throws:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Why compile time and runtime may differ
Sometimes code compiles but fails at runtime:
Real World Use Cases
JAXB-related class loading issues appear in many real situations:
- Legacy enterprise applications upgraded from Java 8 to Java 11.
- Spring or Jakarta-based services that process XML payloads.
- SOAP clients generated from WSDL files.
- Batch jobs that import or export XML files.
- Libraries that still use
javax.xml.bindinternally.
Example scenarios:
- A payment system reads XML settlement files.
- An integration service maps XML requests to Java objects.
- A migration project upgrades the JDK but forgets to add JAXB dependencies.
- A CI pipeline uses Java 17 while local development still uses Java 8.
In all of these cases, the root issue is usually the same: the application assumed JAXB would be present automatically.
Real Codebase Usage
In real projects, developers usually solve this in one of these ways:
Add explicit dependencies
The most common fix is to stop relying on the JDK to provide JAXB and declare it in your build file.
This is better because:
- the project becomes reproducible
- upgrades are easier to manage
- all environments use the same version
Use guard clauses for environment checks
Some teams validate the Java version at startup:
String version = System.getProperty("java.version");
System.out.println("Running on Java " + version);
This does not fix the issue by itself, but it helps detect version-related failures early.
Keep dependencies explicit in build tools
In Maven or Gradle projects, avoid depending on "whatever is in the JDK" for libraries that may be removed later.
Watch for transitive dependencies
A real codebase may fail because a third-party library uses JAXB. In that case:
- inspect your dependency tree
- add the missing JAXB API and runtime explicitly
- upgrade the third-party library if it has a newer compatible version
Common project patterns
- Validation at startup: fail fast if required classes are missing
- Dependency management: pin JAXB versions in Maven/Gradle
- Migration cleanup: replace old
javax-based dependencies carefully if moving to newer Jakarta libraries
Common Mistakes
1. Assuming Java 9 behaves like Java 8
Many developers expect all Java 8 built-in APIs to still be available automatically.
Broken assumption:
import javax.xml.bind.JAXBException;
This import is fine in source code, but it does not guarantee the class exists at runtime.
2. Fixing compile errors but not runtime errors
A project may compile in the IDE and still fail when packaged or deployed.
Avoid this by checking both:
- compile classpath
- runtime classpath or module path
3. Adding only the API without the runtime implementation
Broken setup:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
This gives you the API types, but you often also need the implementation:
<dependency>
<groupId>org.glassfish.jaxb
jaxb-runtime
2.3.3
Comparisons
| Situation | JAXB availability | Typical fix |
|---|---|---|
| Java 6–8 | Included in JDK by default | Usually no extra setup |
| Java 9–10 | Present as module, not always loaded automatically | Add --add-modules java.xml.bind or require the module |
| Java 11+ | Removed from JDK | Add JAXB dependencies manually |
ClassNotFoundException vs NoClassDefFoundError
| Error | Meaning |
|---|---|
ClassNotFoundException | Code explicitly tried to load a class and failed |
NoClassDefFoundError | A class was expected during runtime, but the JVM could not find it |
Cheat Sheet
Quick fix guide
- Java 8 or earlier: JAXB is usually included.
- Java 9 or 10: add the module.
- Java 11+: add dependencies.
Java 9/10 command
java --add-modules java.xml.bind Main
module-info.java
module my.app {
requires java.xml.bind;
}
Maven dependencies for older javax-style code
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</>
2.3.3
FAQ
Why did JAXB stop working after upgrading from Java 8 to Java 9?
Java 9 introduced the module system. JAXB was no longer available by default in the same way it was in Java 8.
How do I fix javax.xml.bind.JAXBException on Java 9?
Use --add-modules java.xml.bind or declare requires java.xml.bind; in module-info.java.
Why does the same fix not work on Java 11?
Because JAXB was removed from the JDK in Java 11. You must add external dependencies.
Do I need both JAXB API and runtime?
Usually yes. The API provides interfaces and classes, and the runtime provides the implementation used during execution.
What is the difference between javax.xml.bind and jakarta.xml.bind?
They are different package namespaces from different stages of the ecosystem. Your imports and dependencies must match.
Can a third-party library cause this error even if my code does not use JAXB directly?
Yes. If a dependency uses JAXB internally and it is missing at runtime, your application can still fail.
Is this a compile-time problem or a runtime problem?
Most often it is a runtime problem, especially when the error is NoClassDefFoundError.
Should I rely on JDK-bundled libraries in modern Java projects?
It is safer to declare important dependencies explicitly in your build configuration.
Mini Project
Description
Build a small Java program that converts a Java object into XML using JAXB. The purpose is to practice making JAXB available correctly on modern Java versions instead of assuming it comes from the JDK automatically.
Goal
Create and run a JAXB-based Java program successfully on Java 11+ by adding the correct dependencies.
Requirements
- Create a
Personclass with at least one field. - Use JAXB to marshal a
Personobject into XML. - Configure the project so it works on Java 11 or later.
- Print the generated XML to the console.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.