java - 多模块项目构建期间模块之间的 Maven 依赖关系解析
问题描述
我遇到了一些以前没有预料到的 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 文件
解决方案
为了清楚起见,您注意到这个从多模块项目运行的命令的行为:
mvn clean test
但是您将具有相同的行为,即:在模块之间解决依赖关系并使其可用,而无需事先将它们安装在本地存储库中,并且运行任何阶段,例如:
mvn test
mvn compile
mvn package
事实上,关于这一点的 Maven 文档并不明确。
您可以阅读使用多个模块的指南:
反应堆
Maven 中处理多模块项目的机制称为反应器。Maven 核心的这一部分执行以下操作:
收集所有可用的模块来构建
将项目排序为正确的构建顺序
按顺序构建选定的项目
你可以猜到,如果模块的顺序对 Maven 构建很重要,这可能意味着模块的构建依赖于先前构建的依赖模块的构建。如果您在依赖项中指定的顺序<modules>
不正确(正确的顺序是必须在用户依赖项之前声明使用的依赖项),这解释了反应器完成的排序。
当然,在某些用例中,您希望将 maven 工件安装到本地存储库中,例如(并非详尽无遗):
- 你不使用多模块项目
- 整个多模块项目的构建很长。您只需要构建一些特定的工件来获得空闲时间,因此无需构建多模块项目。
- 多模块项目中包含的一个或多个模块被其他项目共享/使用。
通过使用-X
标志(调试标志)执行 Maven 构建命令,您将看到 Maven 计算每个模块构建的模块之间的依赖关系。
例如,对于您的示例,您应该看到impl
build :
调试] === 项目构建计划 ================================================= [调试] 项目:A:impl:0.0.1-SNAPSHOT [DEBUG] 依赖项(收集):[] [DEBUG] 依赖(解决):[编译,测试]
稍后检测模块间依赖关系:
[调试] A:impl:jar:0.0.1-SNAPSHOT [调试] A:api:jar:0.0.1-SNAPSHOT:compile
以下是更详细的摘录:
[调试] ================================================= ========================= [DEBUG] 依赖收集统计信息:{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} [调试] A:impl:jar:0.0.1-SNAPSHOT [调试] A:api:jar:0.0.1-SNAPSHOT:compile
因此,在构建过程中执行的插件impl
也将具有包含模块编译类的类路径api
。
例如编译器插件执行的调试跟踪显示:
[信息] --- maven-compiler-plugin:3.1:compile (default-compile) @ impl --- ... [调试] (f) 类路径元素 = [C:\...\test-parent-pom\impl\target\classes, C:\...\test-parent-pom\api\target\classes]
推荐阅读
- google-apps-script - 获取最后一行数据、忽略公式并使用行数据发送电子邮件 - Google Apps 脚本
- c - 当所有值都有效时如何终止可变长度数组?
- python - 在一组数据中查找局部最大值
- swift - NSRange 在 iOS13 上的位置不起作用
- c# - 序列化远程过程调用的参数
- gradle - 排除所有模块中的依赖项,Gradle 中的一个除外
- c# - 使用 Process 运行带有隐藏窗口的旧程序
- vue.js - vuetify 中的 v-app-bar 和 v-toolbar 有什么区别?
- javascript - 指针事件在移动设备上无法正常工作
- jsf - h:dataTable 显示正确的数字但空白行