Question

How to Fix javax.xml.bind.JAXBException NoClassDefFoundError in Java 9+

javajaxbjava-9java-11java-10

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.

Take Quiz

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>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.3</version>
    </dependency>
</dependencies>

Gradle example

dependencies {
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3'
    implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.3'
}

Example using JAXB

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Main {
    public static void main(String[] args) throws Exception {
        Person person = new Person();
        person.name = "Ava";

        JAXBContext context = JAXBContext.newInstance(Person.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(person, System.out);
    }
}

class Person {
    public String name;
}

This code works only if the JAXB API and implementation are available at runtime.

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:

  1. The JVM starts Main.main().
  2. The line JAXBContext.newInstance(Person.class) is executed.
  3. The JVM tries to load the JAXBContext class.
  4. JAXBContext depends on JAXB classes such as JAXBException and an implementation.
  5. If those classes are not available in the runtime environment, class loading fails.
  6. The JVM throws:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Why compile time and runtime may differ

Sometimes code compiles but fails at runtime:

  • Your IDE may include extra libraries.
  • Your build tool may compile with one JDK and run with another.
  • A library may reference JAXB internally, so the failure appears only when that code path runs.

This is why NoClassDefFoundError often points to a runtime classpath or module problem, not a syntax problem in your code.

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.bind internally.

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.

Take Quiz

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
  • Error handling: log the root cause clearly instead of only logging top-level startup failure

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</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

4. Mixing incompatible javax and jakarta packages

Older code often imports:

import javax.xml.bind.JAXBContext;

Newer Jakarta versions may use:

import jakarta.xml.bind.JAXBContext;

These are not interchangeable. Use versions that match your codebase.

5. Using --add-modules on Java 11+

This works for Java 9 or 10, but not for Java 11+, because JAXB was removed from the JDK.

6. Ignoring third-party library dependencies

Your code may not mention JAXB, but a framework or older library might. If you see NoClassDefFoundError, inspect the full stack trace and dependency tree.

Comparisons

SituationJAXB availabilityTypical fix
Java 6–8Included in JDK by defaultUsually no extra setup
Java 9–10Present as module, not always loaded automaticallyAdd --add-modules java.xml.bind or require the module
Java 11+Removed from JDKAdd JAXB dependencies manually

ClassNotFoundException vs NoClassDefFoundError

ErrorMeaning
ClassNotFoundExceptionCode explicitly tried to load a class and failed
NoClassDefFoundErrorA class was expected during runtime, but the JVM could not find it

JDK-provided library vs external dependency

ApproachProsCons
Rely on JDK bundled APILess setup in older Java versionsBreaks across JDK changes
Declare dependency explicitlyReproducible and clearerRequires dependency management

javax.xml.bind vs jakarta.xml.bind

PackageCommon usage
javax.xml.bindOlder Java/JAXB codebases
jakarta.xml.bindNewer Jakarta ecosystem versions

Choose the package and library versions that match the rest of your project.

Take Quiz

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</artifactId>
    <version>2.3.3</version>
</dependency>

What the error means

java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Meaning: the JVM could not find the JAXB class at runtime.

Common rules

  • Imports do not guarantee runtime availability.
  • Java 9 introduced modules.
  • Java 11 removed JAXB from the JDK.
  • API jar alone may not be enough; you may also need a runtime implementation.
  • Do not mix javax.xml.bind and jakarta.xml.bind accidentally.

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.

Take Quiz

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

  1. Create a Person class with at least one field.
  2. Use JAXB to marshal a Person object into XML.
  3. Configure the project so it works on Java 11 or later.
  4. Print the generated XML to the console.
Take Quiz

Keep learning

Related questions

View more