Вопрос или проблема
Я работаю над обновлением проекта с Java 8 до Java 11.
Проект использует сценарий сборки ant, который вызывает wsimport
, который, как я узнал, был устаревшим и больше не включается в JDK. Не стоит беспокоиться, меня заверили, я могу добавить библиотеки в classpath и использовать новый сценарий wsimport.sh
, и все должно быть в порядке.
Но это не так.
Проект включает сгенерированный код, для которого мы получаем файл WSDL из другого источника. Похоже, что этот файл WSDL использует импорты javax
, а не более новые импорты jakarta
. Таким образом, обновление с javax на jakarta невозможно.
В данный момент, когда я запускаю свой wsimport.sh
на файле WSDL, я получаю экран, полный трассировки стека Java, которая начинается с:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/activation/DataSource
Профессор Гугл говорит мне, что это результат отсутствия какой-либо версии activation.jar
в моем classpath, но у меня есть javax.activation.jar
, который лежит прямо в моей директории lib
. Открыв wsimport.sh
, я даже добавил -cp ./lib/*
к вызову исполняемого файла java
. Никакого успеха.
Результаты также говорят, что мне просто нужно “обновить свои зависимости Maven”, что может быть по сути греческим. Я не думаю, что мы используем Maven.
В своем, казалось бы, исчерпывающем поиске в Гугле и StackOverflow, я в конечном итоге наткнулся на этот пост в блоге:
https://nipafx.dev/java-11-migration-guide/
…в котором в разделе об удалении модулей Java EE читается, в частности:
“Если вы пронесете это через компилятор, но забудете подготовить время выполнения, вы получите NoClassDefFoundError:”
Что именно автор поста имеет в виду под “подготовкой времени выполнения”? Я проверил, что использую JDK Java 11 и исполняемый файл java
с помощью java -version
и java -XshowSettings:properties
. Последний даже показывает, что javax.activation.jar
загружается в classpath. Насколько мне известно, я не делал ничего, связанного с JRE. Нужно ли мне это?
Я подозреваю, что это может быть несовместимость версий между моим JAXB-RI и моим файлом jaxws-tools.jar
, но мне не удалось найти список совместимых версий.
Мне кажется, что я пропускаю что-то очевидное, но Java никогда не была моей сильной стороной. Что именно я пропускаю?
Ответ или решение
Ошибка NoClassDefFoundError при обновлении с Java 8 на Java 11: Решение проблемы
Обновление проекта с Java 8 на Java 11 может вызвать на первый взгляд непредсказуемые ошибки, такие как NoClassDefFoundError: javax/activation/DataSource. Эта проблема распространена при переходе к более новым версиям Java, особенно из-за изменений в модульной структуре и удаления некоторых библиотек Java EE из JDK. В данной статье мы рассмотрим эту проблему более подробно и предложим возможные решения.
Корень проблемы
Отсутствие библиотек Java EE:
В Java 11 многие модули Java EE, которые были доступны в предыдущих версиях JDK, были удалены. Это включает в себя библиотеки, такие как javax.activation
. Если ваш проект зависит от этих библиотек, необходимо будет добавить их вручную.
Шаги по решению проблемы
-
Добавление необходимых библиотек:
- В случае с
javax.activation
, вам понадобится добавить библиотекуjavax.activation
. На момент написания статьи, вы можете использовать Jakarta Activation, которая является новой версией. - Скачайте
.jar
файл и поместите его в директориюlib
вашего проекта.
- В случае с
-
Обновление build-скрипта:
Убедитесь, что ваш скриптwsimport.sh
, используемый для генерации кода на основе WSDL файлы, правильно указывает на класс-путь с добавлением новой библиотеки:#!/bin/bash java -cp "./lib/*:your-other-dependencies" com.sun.tools.ws.wscompile.WsimportTool "$@"
-
Проверка версии JDK:
Проверьте, что вы действительно используете Java 11. Выполните команду:java -version
Убедитесь, что вывод указывает на Java 11. Если вы по-прежнему используете JDK 8, необходимо его обновить.
-
Виртуальная машина Java (JRE):
Вам не нужно отдельно устанавливать JRE для вашей системы, так как JDK включает его. Однако, важно, что ваш класс-путь правильно настроен для сборки и выполнения приложения. -
Проверьте зависимости:
Если вы используете какие-то дополнительные зависимости, такие какjaxb
или другие инструменты, убедитесь, что они также совместимы с Java 11. Возможно, вам придется обновить их версии или подключить соответствующие.jar
файлы.
Пояснение фразы «massage the run time»
Автор блога, на который вы ссылаетесь, говорит о необходимости "massage the run time", что указывает на то, что необходимо тщательно проверять и настраивать окружение выполнения программы. Это включает в себя:
- Убедиться, что все нужные библиотеки есть в classpath.
- Настроить правильные версии библиотек, чтобы избежать конфликта между ними.
- Проверить дополнительные зависимости, которые могут повлиять на компиляцию и выполнение программы.
Заключение
Существование ошибки NoClassDefFoundError при обновлении на Java 11 может оказаться неожиданным и разочаровывающим, особенно для разработчиков, не знакомых с изменениями, произошедшими в модульной системе Java. Однако, следуя предложенным шагам, вы сможете успешно настроить ваше окружение и разрешить проблемы, связанные с отсутствующими классами. Если у вас возникают дополнительные вопросы или сложности, рассмотрите возможность консультации с более опытными коллегами или сообществом по Java.