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

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

1. Вступление

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

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

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

Одной из наиболее обсуждаемых особенностей Java 9 является модульная система. The goal of the Java 9 module system is to break apart the core JVM classes and related projects into stand-alone modules. Это помогает нам создавать приложения с меньшими размерами, включая только минимально необходимые классы для запуска.

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

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

NoClassDefFoundError: javax/xml/bind/JAXBException

Чтобы обойти этоwe must include the java.xml.bindmodule. Как мы увидим ниже, для этого есть несколько способов.

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

Самый быстрый способ убедиться, что классы JAXB API доступны для приложения, - это добавитьuse the –add-modules command line argument:

--add-modules java.xml.bind

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

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

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

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

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

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

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

Решение -utilize a dependency management tool such as Maven. При таком подходе мы добавим библиотеку JAXB API в качестве зависимости, как и любую другую библиотеку:


    javax.xml.bind
    jaxb-api
    2.3.0

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

Также имейте в виду, чтоMaven artifact names may be different than the Java 9 module name, как в случае с JAXB API. Его можно найти наMaven Central.

5. Заключение

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

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