运行mvn依赖项时,Maven无法识别兄弟模块:


90

我正在尝试建立一个多模块Maven项目,并且模块间的依存关系显然没有正确设置。

我有:

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

在父POM(其具有包装型POM),然后子目录commons/storage/其限定具有相同名称的JAR POMS。

存储取决于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

为什么即使反应堆由于成功处理了其依赖关系树而明显看到了对“公共”的依赖关系,却还是失败了?它绝对不应该在网上找到,因为它就在那里...

存储的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引用的。这对我来说很直观,如果我在同一个源代码树中有两件事,则不必安装中间产品来继续构建。希望我的想法在这里有意义。


2
啊,编辑是完美的。你为什么不写这个第一本意呢?另外,也许考虑更改标题:)我并不是说要挑剔,这只是为了清楚和分类。这将在将来搜索相似的问题(对与dependency:tree有关的实际标题和内容不清楚)时对整个社区有所帮助
Pascal Thivent

1
你好 找到解决方案了吗?我也有这个问题:(

1
编译会失败吗,还是仅依赖关系:树目标会失败?请参阅Don Willis的答案。
metamatt 2011年

OMG在一个模块中是否由于无法找到另一个模块的符号而失败,因此应将另一个作为依赖项添加并安装为JAR?这是关键....
WesternGun

令人遗憾的是,maven 3.6尚未解决此问题
yuxh

Answers:


21

我认为问题在于,当您指定依赖项时,Maven希望将其打包为jar(或其他任何形式)并至少可以从本地回购中获得。我敢肯定,如果您先运行mvn installCommons项目,那么一切都会正常进行。


4
有没有一种方法可以指定我希望它使用源代码树中模块的任何版本?我认为这种情况会自动处理。我不想/不认为Maven每次我只想制作整个项目时都必须必须进行build-install-build-install-build!
史蒂文·斯兰斯克

38
您是正确的,正在运行的安装程序可以修复该问题。但是,现在每次更改时我都必须安装,这不是我想要的。我希望存储项目从commons项目中获取最新代码。
史蒂文·史兰斯克

实际上,我不得不处理类似的问题,但是,到目前为止,我还找不到答案。看起来Maven不在乎依赖项是否已链接到您的模块,它只是立即回购。我会在您的问题上加上“我的收藏”-也许有些大师会回答。我有兴趣了解是否可以做到
波士顿,

@Steven,请把您的问题作为另一个问题发表,在评论中回答这个问题并不方便,这是另一个主题。
Pascal Thivent 09年

6
我只是想澄清一下,这打算成为主要问题。我是否没有在原始问题中明确指出我的意图是不要求将已构建的产品放在本地存储库中以在同一项目中构建其他模块?
史蒂文·斯兰斯克

104

就像在这个maven邮件列表线程中讨论的那样,dependency:tree目标本身将在存储库而不是反应堆中查找内容。您可以按照之前的建议通过mvn安装来解决此问题,或者做一些较费劲的事情来调用反应堆,例如

mvn compile dependency:tree

为我工作。


2
感谢您的廉价解决方法。但这是一个错误吗?我期望dependency:tree目标依赖于反应堆而没有任何技巧。
mcoolive

应该注意的是,对于全局运行的任何任务,也会发生相同的情况,但只会影响某些子项目。
tkruse

不幸的是,compile触发了传递依赖的下载。还有没有一种方法可以列出依赖关系树而不实际下载它们(当然,POM除外)?
sschuberth '17

对于其他目标,我也有同样的问题。添加compilevalidate还不够)对那里也有帮助:mvn compile animal-sniffer:check以及mvn compile org.basepom.maven:duplicate-finder-maven-plugin:check
msa19,19年

根据您的构建,某些模块可能还依赖于以后阶段构建的工件。就我而言,ZIP文件(使用maven-assembly-plugin)是分阶段构建的package,因此我需要执行例如mvn package animal-sniffer:check
msa19,2016年

6

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

通过执行反应堆构建,可以执行无需安装即可解决依赖关系的构建。

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

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

这是一些描述这种情况的参考


1
有什么方法可以构建单个模块,而无需先安装依赖项,也无需构建完整的父项目?
已退出-Anony-Mousse 2013年

1
为了完成答案-如果直接(无阶段)调用插件,例如mvn dependency:tree,除非您调用compile阶段,否则它仍不会解析源代码中的依赖项。因此,它可以代替:mvn compile dependency:tree
Stanislav Bashkyrtsev

3

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

 <packaging>pom</packaging>

父母有

绒球

我的模型部门有pom-因此没有找到罐子。


那对我抛出了这个错误:解析读取POM的错误。原因:无法识别的标签:“包装中”
hithwen

编辑:我的意思是<packaging> pom </ packaging>修复它。替换<packaging> jar </ packaging>
bsautner 2013年

4
这解决了问题中描述的问题,但是现在子模块不再产生可导出的档案(即jar,wars,ears)。
sheldonh 2014年

sheldonh您是否找到解决此错误并产生可导出存档的解决方案?
user3853134

3

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

我有

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

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

我不明白问题是什么。


1
这就是为什么我必须创建多模块项目时使用gradle的原因。:(
卓颖

2

在这样的Maven模块结构中:

- parent
  - child1
  - child2

您将在parent pom此:

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

如果你现在依赖于child1child2通过将以下在你<dependencies>child2

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

您将收到一个错误,child1找不到该JAR 。这可以通过在for中声明一个<dependencyManagement>块来解决:child1pomparent

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

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


2

Bonusing关闭答案唐·威利斯

如果您的构建创建了测试罐以在反应堆子模块之间共享测试代码,则应使用:

mvn test-compile dependency:tree

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.