Перейти к основному содержимому

Обработка NoClassDefFoundError для JAXBException в Java 9

· 3 мин. чтения

1. Введение

Все , кто пробовал обновиться до Java 9, вероятно, сталкивались с ошибкой NoClassDefFoundError при компиляции кода, который ранее работал в более ранних версиях Java.

В этой статье мы рассмотрим общий отсутствующий класс JAXBException и различные способы его решения. Представленные здесь решения обычно применимы к любому классу, который может отсутствовать при обновлении до Java 9.

2. Почему Java 9 не может найти JAXBException ?

Одной из наиболее обсуждаемых особенностей Java 9 является модульная система. Цель модульной системы Java 9 — разделить основные классы JVM и связанные проекты на автономные модули . Это помогает нам создавать приложения меньшего размера за счет включения только минимально необходимых классов для запуска.

Недостатком является то, что многие классы больше не доступны в пути к классам по умолчанию. В этом случае класс JAXBException можно найти в одном из новых модулей Jakarta EE с именем java.xml.bind . Поскольку этот модуль не требуется основной среде выполнения Java, по умолчанию он недоступен в пути к классам.

Попытка запустить приложение, использующее JAXBException , приведет к:

NoClassDefFoundError: javax/xml/bind/JAXBException

Чтобы обойти это , мы должны включить модуль java.xml.bind . Как мы увидим ниже, есть несколько способов сделать это.

3. Краткосрочное решение

Самый быстрый способ убедиться, что классы JAXB API доступны приложению, — добавить аргумент командной строки –add-modules :

--add-modules java.xml.bind

Однако это не может быть хорошим решением по нескольким причинам.

Во-первых, аргумент –add-modules также является новым в Java 9. Для приложений, которые должны работать на нескольких версиях Java, это создает некоторые проблемы. Нам пришлось бы поддерживать несколько наборов файлов сборки, по одному для каждой версии Java, на которой работает приложение.

Чтобы обойти это, мы также можем использовать аргумент командной строки -XX:+IgnoreUnrecognizedVMOptions для старых компиляторов Java.

Однако это означает, что любая опечатка или неправильно написанный аргумент не будут доведены до нашего сведения. Например, если мы попытаемся установить минимальный или максимальный размер кучи и опечатаемся в имени аргумента, мы не получим предупреждение. Наше приложение все равно запустится, но оно будет работать с другой конфигурацией, чем мы ожидаем.

Во-вторых, опция –add-modules будет объявлена устаревшей в будущем выпуске Java. Это означает, что в какой-то момент после обновления до новой версии Java мы столкнемся с той же проблемой использования неизвестного аргумента командной строки и должны будем решить эту проблему снова.

4. Долгосрочное решение

Существует лучший подход, который будет работать в разных версиях Java и не сломается в будущих версиях.

Решение состоит в том, чтобы использовать инструмент управления зависимостями, такой как Maven . При таком подходе мы бы добавили библиотеку API JAXB в качестве зависимости, как и любую другую библиотеку:

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>

Приведенная выше библиотека содержит только классы JAXB API, включая JAXBException . В зависимости от приложения нам может понадобиться включить другие модули.

Также имейте в виду, что имена артефактов Maven могут отличаться от имен модулей Java 9 , как в случае с JAXB API. Его можно найти на Maven Central .

5. Вывод

Модульная система Java 9 обеспечивает ряд преимуществ, таких как уменьшение размера приложения и повышение производительности.

Однако это также приводит к некоторым непредвиденным последствиям. При обновлении до Java 9 важно понять, какие модули действительно требуются приложению, и предпринять шаги, чтобы убедиться, что они доступны в пути к классам.