【问题标题】:How come my pom.xml dependency isn't found for my Jenkins plugin?为什么我的 Jenkins 插件找不到我的 pom.xml 依赖项?
【发布时间】:2018-02-10 17:18:40
【问题描述】:

我的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 插件需要我上传从 Maven 创建的 hpi 文件。它没有根据输出 jar 运行。如果我继续使用 Jenkins 盒子并手动将 xom JAR 放入 WEB-INF/libs,它就可以工作。但显然这意味着这个插件不适合其他人,这是弄巧成拙的。

这是导致错误的最少代码:https://github.com/DaveStein/parser-sample

自述文件有准确的复制步骤。

关于所选答案的说明 我的示例 repo 的 PR 让我大部分时间到达了我需要的地方。我确实有一些其他问题需要解决,但 JSONObject 冲突是核心问题。我按照 Jesse 的 PR 建议取出了所有 GlobalConfiguration。可能与未来查看者有关的唯一其他问题是在使用 xom 作为显式依赖项时出现一些故障,同时在本文发布时还为 org.jenkins-ci.plugins 使用高于 1.626 的版本。

【问题讨论】:

  • 你在构建一个 uber jar 吗?您需要使用程序集或shade插件将您的依赖项添加到jar文件中。
  • @puhlen 这些插件是用于 java 还是用于 Jenkins 的上下文?我以为 Maven 应该自己管理依赖关系,那为什么需要插件呢?
  • 那些是 maven 插件。在 Maven 中,一切都由插件完成,插件将您的依赖项打包到 jar 中。 Maven 确实会为您处理这个问题,但您需要告诉它您想要(通过添加和配置插件)
  • @puhlen 在 Jenkins 的上下文中,我必须上传一个 hpi。正如您所说,这些插件是关于在 JAR 中添加更多内容。但无论哪种方式,我的 JAR 都没有被 Jenkins 使用。
  • 我不熟悉 .hpi 文件。看起来像一个詹金斯插件文件?你不需要 jenks 插件来构建一个胖 jar。你是什​​么意思你不使用罐子?

标签: java maven jenkins


【解决方案1】:

在第一次加载此依赖项时可能发生 jenkins 错误,现在它被认为是完整的。尝试从 jenkins 的 maven 本地存储库中删除依赖项并重新运行。这可能对你有帮助

【讨论】:

    【解决方案2】:

    我的猜测是 XOM jar 的本地版本与您的 Maven 版本中使用的不同。要验证使用dependency:list Maven 命令列出所有依赖项。验证列出的 XOM 依赖项是否与本地 jar 版本相同。

    【讨论】:

      【解决方案3】:

      Jenkins 核心捆绑包json-lib。 (一个分叉的副本,对于这个问题来说并不重要。)它确实 not 捆绑了可选的依赖项¹ XOM,不管是什么。当您的插件加载 XmlSerializer.class 时,它由 Jenkins 核心的类加载器定义,然后尝试链接到诸如 nu.xom.Node 之类的类。由于这在 XmlSerializer 的定义加载器中不可用——Jenkins 核心类加载器(或多或少 jenkins.war!/WEB-INF/lib/*.jar)——你会得到一个错误。在您的插件类加载器中可以访问名为 的类这一事实并不重要,请原谅双关语。

      如果您的插件需要使用自己的类版本,这些版本通常捆绑在 Jenkins 核心中并隐式地暴露给插件,那么它不仅需要捆绑这些 JAR(一个常规的 compile-scoped Maven 依赖项就足够了) ),但也可以使用pluginFirstClassLoader option。在尝试这样做之前,您最好彻底了解 Java 类加载语义,否则您将迷失在 ClassCastExceptions 和 LinkageErrors 的神秘迷宫中。

      顺便说一句,通常用于迭代测试插件代码的mvn hpi:run 命令模拟了一个现实的类加载机制。因此,如果您在此空间中使用 pluginFirstClassLoader 或任何其他技巧,请始终通过(重新)在示例 Jenkins 实例中安装 *.hpi 来仔细检查生成的类加载行为,例如使用 /pluginManager/advancedinstall-plugin CLI 命令。从您的描述来看,您已经在这样做了(并且可能不知道hpi:run)。

      ¹这里的原罪是使用optional 依赖项。 json-lib 应该定义一个独特的工件 json-lib-xom,硬依赖于 json-libxom。这将确保任何给定的类加载器都可以看到XmlSerializer 它的依赖关系,或者两者都看不到。

      ²JDK-6273389 没有进展,唉。标记为重复,但它是什么重复,我不确定。从理论上讲,Java 9 模块通过施加如此繁重的限制使得像 Jenkins 这样的应用程序一开始就无法使用该模块系统,从而使此类问题变得过时。

      【讨论】:

      • 查看上面更新的 POM...当我去安装 HPI 时,我的 Jenkins 服务器说:WARNING: Failed to load my.package.MyClass$DescriptorImpl jenkins_1 | java.lang.LinkageError: loader constraint violation: loader (instance of hudson/PluginFirstClassLoader) previously initiated loading for a different type with name "net/sf/json/JSONObject"
      • 你已经警告过其他类型的错误,所以我想知道我的 pom 和父 pom 之间是否存在冲突。
      • 不确定。但对于初学者,您应该使用 2.x 父 POM,而不是指定 maven-hpi-plugin 的版本。
      • 源代码的特定内容可能很重要。确实,最好发布一个完整的、可运行的、minimal、自包含的测试用例,例如在 GitHub 上。否则,查看您的问题的人无法自行尝试,或者提供重要的解决方案。
      • 并提交了PR 1,展示了它是如何工作的。但这并不适用于所有情况。一般来说,如果您希望覆盖您的插件可能遇到的 API 签名中使用的核心库,就像 json-lib 一样,您需要使用 Maven Shade 插件对您的副本进行物理重新打包,以免发生冲突。跨度>
      【解决方案4】:

      please google "noclassdeffounderror vs class not found" ,这个错误意味着实际上找到了类依赖但在运行时不可用。

      试试这些步骤:

      • 运行mvn clean packagemvn clean install
      • 检查您的 maven 环境是否正确并且有最新的 jars
      • 检查安装的目标项目是否包含所需的jars
      • 检查依赖类型是否被选为运行时,而不仅仅是作为 编译时间在pom.xml

      这里是一个使用运行时依赖的例子:

      <dependency>
        <groupId>group-a</groupId>
        <artifactId>artifact-b</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
      

      【讨论】:

      • 啊,让我试试runtimepom.xml 中的范围。可能就是这样。我看到你更新了你的答案。默认为compile。刚刚在你的帖子之后读到它:)
      • 切换到运行时将错误更改为java.lang.ClassNotFoundException: nu.xom.Node
      • 你能检查安装的目标,看看它是否包含jar(步骤4),你能显示日志和分解的目标war文件
      • 这会直接成为目标吗?或子文件夹?在本地,我看到了我的项目的 jar,但没有看到依赖项 jar。但这不像我在那里看到其他运行良好的依赖项的 jar 文件。在 Jenkins 中,我在目标文件夹下看到了零个罐子。当我在 Jenkins 中调用目标时,我会执行 clean clover:setup test clover:aggregate clover:clover
      • 请注意,这是一个插件,我在本地执行mvn clean package 后上传了hpi
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 2022-12-18
      • 1970-01-01
      • 2017-12-19
      • 2019-04-16
      • 1970-01-01
      相关资源
      最近更新 更多