在多模块项目构建过程中模块之间的Maven依赖关系解析

时间:2018-07-20 08:35:16

标签: java maven multi-module maven-dependency

我遇到了一些以前没有想到的Maven行为。 例如,我们有一个多模块项目A:

A
|
--- api
--- impl

impl模块使用api作为依赖项:

<dependency>
   <groupId>examle</groupId>
   <artifactId>api</artifactId>
</dependency>

当我为整个应用程序运行mvn clean test时,maven成功完成。 当我为impl模块执行相同的命令时,它们的maven失败,并出现以下异常:

[ERROR] Failed to execute goal on project impl: Could not resolve 
dependencies for project A:impl:jar:1.0-SNAPSHOT: Could not find artifact 
A:api:jar:1.0-SNAPSHOT in maven-public

所以我的问题是Maven如何解决不是内置在jar文件中并推送到本地/远程存储库中的依赖项。在所有教程中,都说过maven在本地存储库中寻找依赖项,如果找不到它,那么它将在远程回购中进行搜索,并且对SNAPSHOTS的行为几乎没有什么不同。

但就我而言,我运行测试阶段,即使在目标存储库中也不构建jar文件

1 个答案:

答案 0 :(得分:4)

为清楚起见,您注意到从多模块项目运行的此命令的这种行为:

mvn clean test

,但是您将具有相同的行为,即:解析模块之间的依赖关系并在模块之间使用它们,而无需在运行任何阶段(例如:

)之前将它们安装在本地存储库中
mvn test
mvn compile
mvn package

事实上,关于这一点的Maven文档并不明确。

您可以阅读the Guide to Working with Multiple Modules

  

反应堆

     

参考了Maven中处理多模块项目的机制   以作为反应堆。 Maven核心的这一部分执行以下操作:

     
      
  • 收集所有要构建的模块

  •   
  • 将项目按正确的构建顺序排序

  •   
  • 按顺序构建所选项目

  •   

您可以猜测,如果模块的顺序对于Maven构建很重要,则可能意味着模块的构建依赖于先前构建的相关模块的构建。这解释了如果您在<modules>中指定的顺序在依存关系方面不正确(正确的顺序是所使用的依存关系必须在用户依存关系之前声明)时,反应堆完成的排序。

当然,在某些用例中,您需要将Maven工件安装到本地存储库中,例如(并非详尽无遗):

  • 您不使用多模块项目
  • 整个多模块项目的构建很长。您只希望通过构建一些特定的工件来节省时间,因此无需构建多模块项目。
  • 多模块项目中包含的一个或几个模块由其他项目共享/使用。

通过使用-X标志(调试标志)执行maven build命令,您将看到Maven为每个模块构建计算模块之间的依赖关系。
例如,以您的示例为例,您应该看到impl构建:

DEBUG] === PROJECT BUILD PLAN
================================================

[DEBUG] Project:       A:impl:0.0.1-SNAPSHOT

[DEBUG] Dependencies (collect): []

[DEBUG] Dependencies (resolve): [compile, test]

不久之后,就检测到了模块间的依赖关系:

[DEBUG] A:impl:jar:0.0.1-SNAPSHOT
[DEBUG]    A:api:jar:0.0.1-SNAPSHOT:compile

这是以下内容的更详细摘录:

[DEBUG] =======================================================================
[DEBUG] Dependency collection stats: {ConflictMarker.analyzeTime=23166, ConflictMarker.markTime=13490, ConflictMarker.nodeCount=2, ConflictIdSorter.graphTime=31377, ConflictIdSorter.topsortTime=6158, ConflictIdSorter.conflictIdCount=1, ConflictIdSorter.conflictIdCycleCount=0, ConflictResolver.totalTime=51611, ConflictResolver.conflictItemCount=1, DefaultDependencyCollector.collectTime=368903, DefaultDependencyCollector.transformTime=134014}
[DEBUG] A:impl:jar:0.0.1-SNAPSHOT
[DEBUG]    A:api:jar:0.0.1-SNAPSHOT:compile

因此,在impl构建期间执行的插件还将具有一个类路径,包括api模块的已编译类。
例如,编译器插件执行的调试跟踪显示:

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ impl ---
...
[DEBUG]   (f) classpathElements = [C:\...\test-parent-pom\impl\target\classes, C:\...\test-parent-pom\api\target\classes]