【问题标题】:Maven dependency versioning and java.lang.NoClassDefFoundErrorMaven 依赖版本控制和 java.lang.NoClassDefFoundError
【发布时间】:2009-10-08 16:47:51
【问题描述】:

我有一个 Java 项目 X 依赖于项目 Y(在 pom 文件中)。

我在 Y 中修改并使用 Maven 工具构建 X,Y 然后运行 ​​X(在 JBoss 上)没有问题。

当我在 Y 中添加新类,然后使用 Maven 构建(没有问题),然后运行 ​​X 时,它会为新类抛出 java.lang.NoClassDefFoundError

我认为它是一个 Maven 依赖版本控制或类似的东西......我主要在谷歌搜索,但没有任何效果......如何解决这个问题??

【问题讨论】:

  • 我注意到生成的 x.jar 没有包含 y.jar 的“lib”目录......我手动添加了这个......它运行良好......但是现在,如何制作Maven 会自动执行此操作(如果这是正确的解决方案)?

标签: java maven-2 maven-plugin


【解决方案1】:

Moro,您在评论中写道 X 声明了以下依赖项:

<dependency>
  <groupId>Y</groupId>
  <artifactId>Y</artifactId>
  <scope>provided</scope>
  <version>1.0</version>
</dependency>

第一点。您在这里使用的是“固定”版本(而不是“SNAPSHOT”)。当使用SNAPSHOT 时,maven 会自动抓取最新的SNAPSHOT每次你构建。另一方面,当您使用 1.0 时,一旦 maven 下载了这个工件,它从不尝试获取新的 1.0。因此,您应该增加 Y 的版本,或者,如果 Y 正在积极开发中(增强功能、错误修复等),您应该真正使用 SNAPSHOT。 有关SNAPSHOT 的更多信息,请查看 Sonatype 书中的9.3.1.2. SNAPSHOT Versions 章节:

你为什么要用这个?快照 版本用于项目下 积极发展。如果你的项目 依赖于一个软件组件 正在积极开发中,您可以 取决于 SNAPSHOT 版本,以及 Maven 会定期尝试 下载最新的快照 运行构建时的存储库。 同样,如果您的下一个版本 系统会有一个版本 “1.4”,您的项目将有一个 版本“1.4-SNAPSHOT”,直到它是 正式发布。

第二点。您正在使用 provided 范围。根据章节 9.4.1. Dependency Scope:

provided 依赖项在以下情况下使用 您期望 JDK 或容器 提供他们。例如,如果你是 开发一个 Web 应用程序,你 需要可用的 Servlet API 在编译类路径上编译一个 servlet,但你不想 将 Servlet API 包含在 打包的WAR; Servlet API JAR 是 由您的应用程序服务器提供或 小服务程序容器。 provided 依赖项在 编译类路径(不是运行时)。 它们不是传递的,也不是 打包。

这真的是你想要的吗?您如何在 JBoss 上部署 X 和 Y?你不应该使用默认的compile 范围吗?

【讨论】:

  • 我刚刚使用了 YY1.0-SNAPSHOT 但它没有放lib 目录并且没有运行
  • 那是因为您需要将Y中的版本号更改为1.0-SNAPSHOT,然后运行mvn install。之后,正确的依赖就可用了
  • @Moro 如果没有关于您的 maven 模块(打包、版本...)的更多详细信息,很难猜测到底发生了什么。 X 是什么样的 J2EE 模块?你在 pom.xml 中使用什么样的包装?你能提供你的 pom.xml 文件吗?
  • 你们都更新了 Y\pom.xml 中的版本号和 X\pom.xml 中对它的引用?
【解决方案2】:

添加新类后,您是否在 Y 上运行 mvn install

【讨论】:

    【解决方案3】:

    您是否安装/部署了新版本的 Y,升级了新版本的 X 的依赖项,并重新构建了 X?

    【讨论】:

    • Y pom 的版本为 1.0,X pom 的依赖关系为 YY提供1.0
    【解决方案4】:

    在构建项目 Y 之前,您是否尝试过 mvn clean

    【讨论】:

    • yes clean then install for Y ... and clean then package for X
    【解决方案5】:

    Maven 解析来自本地和远程存储库的依赖项,尽管诸如 m2eclipse 之类的 IDE 插件也将解析作为工作区中项目的依赖项。如果您没有这样的插件,则需要将工件 Y 安装到本地存储库或将其部署到远程存储库,以便您和您的同行可以在 Maven 识别构建项目时进行更改之前访问它十。

    workspace resolution screenshot http://docs.codehaus.org/download/attachments/11403480/project-properties.png

    如果两个项目密切相关,您可以考虑创建一个multi-module build,以便同时构建项目 X 和 Y。

    【讨论】:

    • 1.它在存储库中,因此我使用安装命令 2。它已经是一个多模块项目......我试图在父项目中构建它......但同样的事情
    【解决方案6】:

    好的,抱歉信息迟到了。

    X包是ejb,所以X.jar没有lib目录。

    然后Y.jar应该放在Jboss/server/default/lib中,它可以正常工作。

    谢谢大家。

    【讨论】: