Ошибка NoClassDefFoundError для javax.xml.bind.JAXBException в Java 9 и выше
Привет всем! Я начинающий Java-разработчик, перешел с Java 8 на Java 11 и столкнулся с проблемой при запуске проекта. Раньше все работало отлично, а теперь вылетает ошибка:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at com.example.myapp.MyClass.main(MyClass.java:10)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
Вот мой код (упрощенный пример):
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class XmlSerializer {
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(SomeClass.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(new SomeClass(), System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Проект собирается через Maven. В Java 8 все работало без дополнительных зависимостей, а теперь JAXB не находится. Я слышал, что в Java 9+ убрали JAXB из стандартной библиотеки, но не понимаю, как это исправить. Пробовал добавить зависимости в pom.xml, но все равно ошибка. Подскажите, что делать?
Версия Java: 11.0.2. Maven: 3.8.1. ОС: Windows 10.
<<Проблема: удаление JAXB из стандартной библиотеки в Java 9+
Начиная с Java 9, модуль java.xml.bind (который содержит JAXB API) был помечен как устаревший (deprecated) и удален из стандартного набора модулей. В Java 11 он полностью исключен из JDK. Это означает, что классы из пакета javax.xml.bind больше не доступны по умолчанию. Ошибка NoClassDefFoundError возникает именно из-за этого.
Решение: добавление JAXB как внешней зависимости
Чтобы исправить ошибку, нужно явно подключить JAXB API и его реализацию через систему сборки (Maven, Gradle) или вручную добавить JAR-файлы в classpath. Ниже приведены шаги для Maven.
Шаг 1. Добавьте зависимости в pom.xml
Вам потребуются две зависимости: JAXB API (интерфейсы) и реализация (например, от GlassFish или Eclipse). Вот минимальный набор для Java 11:
<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.3</version>
</dependency>
Обратите внимание: jaxb-runtime включает реализацию, которая раньше была в JDK. Если вы используете Spring Boot или другой фреймворк, убедитесь, что версии совместимы.
Шаг 2. Проверьте версии Java и модули
Если вы используете Java 9 или 10, можно также добавить флаг --add-modules java.xml.bind при запуске, но это временное решение. Для Java 11 этот модуль полностью удален, поэтому флаг не сработает. Лучше всегда использовать внешние зависимости.
Шаг 3. Альтернатива: использование Jakarta EE
С Java 11 и позже JAXB был переименован в Jakarta XML Binding (под пакетом jakarta.xml.bind). Если вы пишете новый проект, рекомендую перейти на Jakarta. Для этого замените зависимости:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>
При этом в коде нужно будет заменить javax.xml.bind на jakarta.xml.bind.
Шаг 4. Проверка classpath
Если вы не используете Maven, скачайте JAR-файлы вручную:
jaxb-api-2.3.1.jarjaxb-runtime-2.3.3.jar- Дополнительно:
javax.activation-api-1.2.0.jar(иногда требуется для старых версий)
Добавьте их в classpath при компиляции и запуске:
javac -cp "jaxb-api-2.3.1.jar;jaxb-runtime-2.3.3.jar" MyClass.java
java -cp ".;jaxb-api-2.3.1.jar;jaxb-runtime-2.3.3.jar" MyClass
Почему это произошло?
Удаление JAXB из JDK связано с переходом Java на модульную систему (Project Jigsaw) и желанием сделать JDK более легковесным. Теперь разработчики сами решают, какие библиотеки подключать. Это дает больше гибкости, но требует явного указания зависимостей.
После добавления зависимостей и пересборки проекта ошибка NoClassDefFoundError исчезнет.
Альтернативный подход: использование флагов JVM (только для Java 9-10)
Если вы временно работаете с Java 9 или 10 и не хотите добавлять внешние зависимости, можно использовать флаг --add-modules. Это включит модуль java.xml.bind, который еще присутствует в JDK:
java --add-modules java.xml.bind -jar myapp.jar
Однако этот метод не работает в Java 11+ и считается устаревшим. Я рекомендую его только для быстрого тестирования или миграции.
Дополнительный совет: проверьте конфликты версий
Иногда ошибка возникает из-за того, что в вашем проекте уже есть JAXB-зависимости, но они конфликтуют (например, разные версии). Используйте команду mvn dependency:tree для анализа дерева зависимостей. Убедитесь, что нет дублирующихся или несовместимых версий JAXB.
Также проверьте, что у вас нет смешанных версий javax.xml.bind и jakarta.xml.bind — это вызовет ошибки компиляции. Если вы переходите на Jakarta, обновите все импорты в коде.
// Пример обновленного импорта для Jakarta
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
В остальном, основное решение — добавить явные зависимости, как описано в первом ответе.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги