简体   繁体   English

在多模块项目构建期间,模块之间的Maven依赖性解析

[英]Maven dependency resolution between modules during a multi-module project build

I faced with some Maven behavior that I was not expected before. 我面对一些Maven的行为,我以前没想到过。 For example we have multi-module project A: 例如,我们有多模块项目A:

A
|
--- api
--- impl

impl module uses api as a dependency: impl模块使用api作为依赖:

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

when I run mvn clean test for whole app maven finishes successfully. 当我运行mvn clean test为整个app maven成功完成。 when I execute same command for impl module them maven fails with exception like: 当我为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

So my question is how maven resolves dependencies that was not build into jar file and pushed into local/remote repositories. 所以我的问题是maven如何解析没有构建到jar文件并推入本地/远程存储库的依赖项。 In all tutorials it is said that maven looks for dependencies in local repository and if it can not find it then it search in remote repo and it has little bit different behavior for SNAPSHOTS. 在所有教程中,据说maven在本地存储库中查找依赖项,如果它找不到它,那么它在远程仓库中搜索,它对SNAPSHOTS有一些不同的行为。

But in my case I run test stage and do not build jar file even in target repo 但在我的情况下,我运行测试阶段,即使在目标仓库中也不构建jar文件

To makes things clear, you noticed this behavior with this command run from the multi-module project : 为了清楚起见,您注意到此命令的这种行为是从多模块项目运行的:

mvn clean test

but you would have the same behavior, that is : getting the dependencies resolved and usable between modules without previously installing them in the local repository with any phase you run such as : 但是你会有相同的行为,即:使模块之间的依赖关系得到解决和使用,而无需先将它们安装在本地存储库中,并运行任何阶段,例如:

mvn test
mvn compile
mvn package

In fact the Maven documentation about this point is not explicit. 事实上,关于这一点的Maven文档并不明确。

You can read in the Guide to Working with Multiple Modules : 您可以阅读使用多个模块的指南

The Reactor 反应堆

The mechanism in Maven that handles multi-module projects is referred to as the reactor. Maven中处理多模块项目的机制称为反应堆。 This part of the Maven core does the following: Maven核心的这一部分执行以下操作:

  • Collects all the available modules to build 收集要构建的所有可用模块

  • Sorts the projects into the correct build order 将项目排序为正确的构建顺序

  • Builds the selected projects in order 按顺序构建选定的项目

You can guess that if the order of the modules matters for the Maven build, it probably means that the build of a module relies on the build of dependent modules that were previously built. 您可以猜测,如果模块的顺序对于Maven构建很重要,则可能意味着模块的构建依赖于先前构建的依赖模块的构建。 That explains the sort done by the reactor if the order you specified in <modules> is not correct in terms of dependencies (the correct order is that the used dependency has to be declared before the user dependency). 这解释了如果您在<modules>指定的顺序在依赖关系方面不正确,则反应堆完成的排序(正确的顺序是必须在用户依赖关系之前声明所使用的依赖关系)。

There are of course some uses cases where you want to install a maven artifact into a local repository such as (not exhaustive) : 当然,有些用例需要将maven工件安装到本地存储库中,例如(不详尽):

  • you don't use a multi module project 您不使用多模块项目
  • the build of the whole multi module project is long. 整个多模块项目的构建很长。 You want spare time by building just some specific artifacts, so without building the multi-module project. 您只需构建一些特定的工件就可以获得业余时间,因此无需构建多模块项目。
  • one or several modules included in the multi module project is shared/used by other projects. 多模块项目中包含的一个或多个模块由其他项目共享/使用。

By executing your maven build command with the -X flag (the debug flag) you will see that Maven computes the dependencies between module for each module build. 通过使用-X标志(调试标志)执行maven build命令,您将看到Maven为每个模块构建计算模块之间的依赖关系。
For example with your example you should see for the impl build : 例如,您的示例应该看到impl构建:

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

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

[DEBUG] Dependencies (collect): []

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

And a little later the detection of the inter-module dependency : 稍后检测到模块间依赖关系:

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

Here is a more detailed extract of : 以下是更详细的摘录:

[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

Consequently, the plugins executed during the build of the impl will also have a classpath including the compiled classes of the api module. 因此,在构建impl期间执行的插件也将具有包括api模块的编译类的类路径。
For example the debug traces of the compiler plugin execution show : 例如,编译器插件执行的调试跟踪显示:

[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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM