[英]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工件安装到本地存储库中,例如(不详尽):
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.