Почему моя зависимость pom.xml не найдена для моего плагина Jenkins?
My pom.xml
имеет эту зависимость:
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
Когда я использую XMLSerializer
, он выдает исключение: java.lang.NoClassDefFoundError: nu/xom/Node
Если я запускаю класс локально и добавляю JAR в мой путь к классам, все работает так, как ожидалось. Я запускаю этот класс в качестве плагина Jenkins, поэтому я не ожидаю, что будет вручную определять путь к классам - я понял, что Maven должен обрабатывать.
Важно отметить, что плагины Jenkins требуют загрузки файла hpi
, который создается из Maven. Он не работает на выходе jar
. Если я поеду на коробку Дженкинса и вручную поставлю JOM XOM в WEB-INF/libs
, он будет работать. Но, очевидно, это означает, что этот плагин не будет для других людей, что саморазрушится.
Ниже приведен минимальный код, вызывающий ошибку: https://github.com/DaveStein/parser-sample
Readme имеет точные этапы воспроизведения.
Примечание по выбранному ответу
PR для моего образца репо доставил мне большую часть пути туда, где я должен был быть. У меня было еще несколько проблем, которые пришлось решить, но конфликт JSONObject был основной проблемой. Я вынул все GlobalConfiguration, как предложил Джесси PR. Единственная проблема, которая может иметь отношение к будущему редактору, - это сбой при использовании xom
как явной зависимости, а также использования более высокой версии, чем 1.626 для org.jenkins-ci.plugins
во время этого сообщения.
Ответы
Ответ 1
Ядерные пучки Дженкинса json-lib
. (Разветвленная копия, а не то, что она имеет значение для целей этого вопроса.) Она не связывает необязательную зависимость¹ XOM, что бы это ни было. Когда ваш плагин загружает XmlSerializer.class
, он определяется загрузчиком классов для ядра Jenkins, который затем пытается связать с такими классами, как nu.xom.Node
. Так как это недоступно в определяющем загрузчике XmlSerializer
- загрузчика основного класса Jenkins (более или менее jenkins.war!/WEB-INF/lib/*.jar
) - вы получаете сообщение об ошибке. Тот факт, что класс по этому имени доступен в вашем загрузчике класса плагинов, не является импортом, извините за каламбур.
Если вашему плагину необходимо использовать собственные версии классов, которые обычно входят в ядро Jenkins и неявно подключены к плагинам, тогда ему необходимо не только связывать эти JAR (для этой цели достаточно регулярной compile
-основной зависимости Maven), но также использовать параметр pluginFirstClassLoader
. Прежде чем пытаться это сделать, вам лучше понять семантику загрузки классов Java, или вы потеряетесь в лабиринте cryptic² ClassCastException
и LinkageError
s.
Кстати, команда mvn hpi:run
, обычно используемая для проверки кода плагина, итеративно не моделирует реалистичный режим загрузки классов. Поэтому, если вы используете pluginFirstClassLoader
или любые другие трюки в этом пространстве, всегда проверяйте результирующее поведение загрузки класса путем (повторной) установки *.hpi
в примере Jenkins примера, например, используя /pluginManager/advanced
, или install-plugin
Команда CLI. Судя по вашему описанию, вы уже делали это (и, возможно, не знали о hpi:run
).
¹ Исходный грех здесь - использование зависимостей optional
. json-lib
должен скорее определить отдельный артефакт json-lib-xom
с жесткими зависимостями от json-lib
и xom
. Это гарантирует, что любой заданный загрузчик классов может либо увидеть XmlSerializer
, либо его зависимости, либо нет.
² Нет прогресса на JDK-6273389, увы. Я отмечен как дубликат, но что это дубликат, я не уверен. Теоретически модули Java 9 делают такие вопросы устаревшими, налагая такие обременительные ограничения, что такие приложения, как Jenkins, не могли использовать эту модульную систему для начала.
Ответ 2
please google " noclassdeffounderror vs класс не найден", эта ошибка означает, что зависимость класса фактически найдена, но недоступна во время выполнения.
Попробуйте выполнить следующие действия:
- Запустите
mvn clean package
и mvn clean install
- Проверьте, правильна ли ваша среда maven и есть ли последние баннеры.
- Проверьте, содержит ли установленный целевой проект необходимые банки
- Проверьте, выбран ли тип зависимостей как время выполнения, а не только как
время компиляции в
pom.xml
Ниже приведен пример использования зависимостей времени выполнения:
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
Ответ 3
Я предполагаю, что локальная версия баннера XOM отличается от той, которая используется в вашей версии Maven. Чтобы проверить использование команды dependency:list
Maven для отображения всех ваших зависимостей. Проверьте, соответствует ли указанная зависимость XOM той же версией, что и локальная банка.
Ответ 4
Вероятно, ошибка в jenkins произошла, когда эта зависимость была загружена в первый раз и теперь считается полной. Попробуйте удалить зависимость от локального репозитория maven jenkins и повторно запустить. Это может помочь вам