Как исправить java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException в Java 9, 10, 11?
Всем привет! Я начинающий Java-разработчик, пишу простое приложение для работы с XML. Использую JAXB для преобразования объектов в XML и обратно. Раньше всё работало отлично на Java 8, но после перехода на Java 11 при запуске получаю ошибку:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Вот мой код:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class XmlConverter {
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(User.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
User user = new User("Иван", 25);
marshaller.marshal(user, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
class User {
private String name;
private int age;
// геттеры, сеттеры, конструктор...
}
Я использую:
- Java 11 (OpenJDK)
- Maven для сборки
- Никаких дополнительных зависимостей не подключал
Почему это происходит? Ведь на Java 8 всё работало! Мне нужно срочно починить проект, подскажите, как это исправить?
<<Почему возникает ошибка?
Начиная с Java 9 модуль java.xml.bind (который содержит JAXB API) был помечен как устаревший (deprecated) и по умолчанию исключён из classpath. В Java 11 он и вовсе удалён из стандартной поставки JDK. Это сделано в рамках модульной системы Java (Project Jigsaw).
Раньше JAXB входил в состав JDK (Java SE), но теперь его нужно подключать отдельно как внешнюю библиотеку.
Решение №1: Добавить JAXB как Maven-зависимость (рекомендуется)
Добавьте в ваш pom.xml следующие зависимости:
<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>
Пояснение:
jaxb-api— содержит интерфейсы и аннотации JAXBjaxb-runtime— реализация от GlassFish (можно использовать и Eclipse Implementation —org.eclipse.persistence:org.eclipse.persistence.moxy)javax.activation-api— нужен для корректной работы JAXB в Java 11+
Решение №2: Для Gradle
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'
Решение №3: Использовать --add-modules (только для Java 9-10)
Если вы временно работаете на Java 9 или 10, можно добавить флаги JVM. Но это не сработает на Java 11+:
--add-modules java.xml.bind
Решение №4: Откатиться на Java 8 (не рекомендуется)
Можно просто использовать Java 8, где JAXB всё ещё встроен. Но это временное решение — Java 8 уже не получает обновлений безопасности.
Проверка после исправления
После добавления зависимостей запустите Maven clean install:
mvn clean compile
Ошибка должна исчезнуть. Если нет — проверьте, что зависимости действительно загрузились (папка .m2/repository).
Важно!
Если вы используете Java 17 или новее, рекомендую рассмотреть переход на Jakarta XML Binding (новое имя JAXB после передачи в Eclipse Foundation):
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.0</version>
</dependency>
И импорты заменятся с javax.xml.bind.* на jakarta.xml.bind.*.
Альтернативный подход: Использовать Jackson для работы с XML
Если вы не привязаны именно к JAXB, можно полностью отказаться от него и использовать более современную библиотеку Jackson. Она имеет схожий функционал, но лучше поддерживается в новых версиях Java.
Пример с Jackson XML:
// Добавьте в pom.xml:
// com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.15.2
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JacksonXmlExample {
public static void main(String[] args) throws Exception {
XmlMapper mapper = new XmlMapper();
User user = new User("Петр", 30);
// Сериализация в XML
String xml = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(user);
System.out.println(xml);
// Десериализация из XML
User deserialized = mapper.readValue(xml, User.class);
}
}
Плюсы Jackson:
- Не требует дополнительных модулей JVM
- Работает на всех версиях Java (8, 11, 17, 21)
- Единый API для JSON, XML, YAML и других форматов
- Активно поддерживается сообществом
Минусы:
- Может потребоваться рефакторинг кода
- Некоторые специфические возможности JAXB (например,
@XmlTransient) реализованы иначе
Этот вариант подойдёт, если вы начинаете новый проект или готовы потратить время на замену библиотеки.