ChatGPT解决这个技术问题 Extra ChatGPT

Maven 在运行 mvn dependency:tree 时无法识别兄弟模块

我正在尝试设置一个多模块 Maven 项目,并且模块间依赖项显然没有正确设置。

我有:

<modules>
  <module>commons</module>
  <module>storage</module>
</modules>

在父 POM(具有打包类型的 pom)中,然后是子目录 commons/storage/,它们定义了具有相同名称的 JAR pom。

存储取决于 Commons。

在主(主)目录中,我运行 mvn dependency:tree 并查看:

[INFO] Building system
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] domain:system:pom:1.0-SNAPSHOT
[INFO] \- junit:junit:jar:3.8.1:test
[INFO] ------------------------------------------------------------------------
[INFO] Building commons
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
...correct tree...
[INFO] ------------------------------------------------------------------------
[INFO] Building storage
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
Downloading: http://my.repo/artifactory/repo/domain/commons/1.0-SNAPSHOT/commons-1.0-SNAPSHOT.jar
[INFO] Unable to find resource 'domain:commons:jar:1.0-SNAPSHOT' in repository my.repo (http://my.repo/artifactory/repo)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) domain:commons:jar:1.0-SNAPSHOT

为什么对“commons”的依赖会失败,即使反应器显然已经看到它,因为它成功地处理了它的依赖树?它绝对不应该去'网络找到它,因为它就在那里......

用于存储的 pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <packaging>jar</packaging>
  <parent>
    <artifactId>system</artifactId>
    <groupId>domain</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <groupId>domain</groupId>
  <artifactId>storage</artifactId>
  <name>storage</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <!-- module dependencies -->
    <dependency>
      <groupId>domain</groupId>
      <artifactId>commons</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <!-- other dependencies -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

感谢您的任何建议!

(编辑)

为了澄清,我在这里寻找的是:我不想安装模块 X 来构建依赖于 X 的模块 Y,因为两者都是从同一个父 POM 引用的模块。这对我来说很直观,如果我在同一个源代码树中有两个东西,我不应该安装中间产品来继续构建。希望我的想法在这里有意义......

啊,编辑是完美的。你为什么不一开始就写这个?另外,也许可以考虑更改标题:) 我并不是要挑剔,这只是为了清晰和分类。这将在未来搜索类似问题时对整个社区有所帮助(对于依赖关系:树的实际标题和内容并不十分清楚)
你好。你找到解决方案了吗?我也遇到了这个问题 :(
编译是否失败,或者仅仅是依赖:树目标?见唐威利斯的回答。
OMG 所以在一个模块中,如果它因为找不到另一个模块的符号而失败,另一个应该作为依赖项添加并作为 JAR 安装?这是关键……
遗憾的是 maven 3.6 还没有解决这个问题

B
Beryllium

正如 this maven mailing list thread 中所讨论的,dependency:tree 目标本身将在存储库而不是反应器中查找内容。您可以按照前面的建议通过 mvn 安装来解决这个问题,或者做一些不那么繁琐的事情来调用反应器,例如

mvn compile dependency:tree

为我工作。


感谢您提供廉价的解决方法。但这是一个错误吗?我期望依赖:树目标依赖于反应堆而没有任何技巧。
应该注意的是,任何全局运行的任务都会发生同样的情况,但只会影响一些子项目。
不幸的是,compile 触发了传递依赖的下载。还有一种方法可以列出依赖树而不实际下载它们(当然除了 POM)?
我对其他目标也有同样的问题。添加 compilevalidate 还不够)也有帮助:mvn compile animal-sniffer:checkmvn compile org.basepom.maven:duplicate-finder-maven-plugin:check
根据您的构建,某些模块可能还依赖于在后续阶段构建的工件。在我的例子中,一个 ZIP 文件(使用 maven-assembly-plugin)是在 package 阶段构建的,所以我需要做例如 mvn package animal-sniffer:check
B
Bostone

我认为问题在于,当您指定依赖项时,Maven 期望将其作为 jar(或其他)打包并至少从本地存储库中可用。我敢肯定,如果您首先在您的公共项目上运行 mvn install,那么一切都会正常工作。


有没有办法指定我希望它使用源树中模块的任何版本?我以为这个案子会自动处理。我不想/不认为每次我只想制作整个项目时,Maven 都需要构建-安装-构建-安装-构建!
你是正确的,运行安装修复它。但是,现在我每次进行更改时都必须安装,这不是我想要的。我希望存储项目从公共项目中获取最新代码。
我实际上必须处理类似的问题,唉-到目前为止我无法找到答案。看起来 Maven 并不关心依赖项是否链接到您的模块,它只是立即转到 repo。我会最喜欢你的问题 - 所以也许一些大师会回应。我很想知道这是否可以做到
这本来是主要问题,我只是澄清一下。我在最初的问题中是否没有明确表示我的意图是不要求构建的产品位于本地存储库中以在同一项目中构建其他模块?
(谷歌完整性多年后)正确的答案是将 pom 添加到依赖项中,如 bsautner 所解释
a
adrock20

Don Willis 获得 answer 的奖励:

如果您的构建创建了 test-jars 以在您的反应器子模块之间共享测试代码,您应该使用:

mvn test-compile dependency:tree

在这种情况下,这将允许 dependency:tree 运行完成。


N
Newtopian

意识到这是一个较旧的线程,但似乎该工具已经进化,或者这可能是第一次错过了。

可以通过进行 reactor 构建来执行构建来解决依赖关系而无需安装。

如果您在描述项目模块结构的父级中开始构建,那么您的模块之间的依赖关系将在构建过程中通过内部 Maven 反应器解决。

当然,这不是完美的解决方案,因为它不能解决结构内单个模块的构建问题。在这种情况下,Maven 在他的反应器中将没有依赖项,并且会在存储库中寻找解决它。因此,对于单个构建,您仍然必须先安装依赖项。

下面是一些描述这种情况的reference


有什么方法可以构建单个模块,而无需先安装依赖项,也无需构建完整的父项目?
要完成答案 - 如果直接调用插件(没有阶段)例如 mvn dependency:tree,除非您调用 compile 阶段,否则它仍然不会解析来自源的依赖项。所以这将起作用:mvn compile dependency:tree
m
mba

唯一对我有用的东西:切换到 gradle :(

我有

Parent
  +---dep1
  +---war1 (using dep1)

我可以在 war1 中 cd 并使用 mvn tomcat7:run-war。尽管war1引用了他的父级并且父级引用了war1和dep1(作为模块),但我之前总是必须安装整个项目,因此应该知道所有依赖项。

我不明白问题是什么。


这就是我在创建多模块项目时使用 gradle 的原因。 :(
b
bsautner

对我来说,导致我进入这个线程的是一个类似的问题,解决方案是确保所有模块依赖 pom 都有

 <packaging>pom</packaging>

父母有

绒球

我的模型部门有 pom - 所以找不到罐子。


这给我抛出了这个错误:Parse error reading POM.原因:无法识别的标签:“包装”
编辑:我的意思是 pom 修复了它。替换 jar
这解决了问题中描述的问题,但现在子模块不产生可导出的档案(即罐子、战争、耳朵)。
Sheldonh 您是否找到了解决此错误并生成可导出存档的解决方案?
b
bothor

在这样的 Maven 模块结构中:

- parent
  - child1
  - child2

您将在 parent pom 中拥有:

<modules>
  <module>child1</module>
  <module>child2</module>
</modules>

如果您现在通过将以下内容放入 child2 中的 <dependencies> 中来依赖 child2 中的 child1

<dependency>
  <groupId>example</groupId>
  <artifactId>child1</artifactId>
</dependency>

您将收到无法找到 child1 的 JAR 的错误消息。这可以通过在 parentpom 中声明一个包含 child1<dependencyManagement> 块来解决:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>example</groupId>
      <artifactId>child1</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>

现在,当您在 parent 上运行 compilepackage 等目标时,将构建 child1,并且 child2 将找到 child1 的已编译文件。


s
sergeko

使用版本 >= 3.1.2 的依赖插件似乎可以解决问题。


N
Nitin Kamate

确保失败的模块在 pom 中得到解决,通过在模块的 pom 文件中包含配置来指向正确的父级。