不确定这是否是一个 Maven 错误,或者是我们未能按预期使用 Maven,所以我首先在这里询问,而不是直接转到 apache jira。关注 maven v.3.9.0,但 v.3.9.6 和最新的 4.0.0-alpha-13 似乎也会发生这种情况。
在我们的项目中,我们使用 Maven 多模块构建设置(100+ 模块)。所有模块的完整构建需要一个多小时,因此我们使用 gitflow-incremental-builder maven 插件来构建适合开发过程不同阶段的子集。例如,PR 构建仅构建已更改的模块以及依赖于它们的模块。在 CI 中,我们有一个管道,在成功 PR 构建后,使用 maven-release-plugin 仅构建已更改模块的发布 jar 并将它们部署到 Azure Artifacts。
这里需要注意的一件事是,我们广泛使用范围来依赖于我们构建的 jar。对于范围和快照应该如何关联,社区中似乎存在一些长期的分歧。所以也许这也是问题的一部分。
PR 构建类路径由在同一多模块构建期间烘焙的快照 jar 以及来自 Azure 远程存储库的不属于 PR 构建模块子集的模块的最新发行版本组成。不久前,我们开始遇到 PR 构建失败的情况,因为依赖范围未解析为同一构建期间先前烘焙的快照,而是解析为远程存储库中的最新版本。即使快照位于本地存储库中,并且快照版本(例如 1.2.3-SNAPSHOT)应被视为比之前的发行版本(例如 1.2.2)更新,也会发生这种情况。在maven上进行一些调试后,我注意到执行聚合器类型的mojos(在我们的例子中是serenity-maven-pluginsaggregate-goal)会导致所有模块/项目的依赖关系被解析,但此时尚未完成该操作。这种情况发生在模块的中间,并且稍后不会重新解析使用的范围,缺少快照 jar 仍需在构建过程中稍后生成。
Maven 代码似乎转向了 org.apache.maven.lifecycle.internal.Mojoexcutor.java:252 上的错误路径
public void ensureDependenciesAreResolved(MojoDescriptor mojoDescriptor, MavenSession session, DependencyContext dependencyContext) throws LifecycleExecutionException {
MavenProject project = dependencyContext.getProject();
boolean aggregating = mojoDescriptor.isAggregator();
Collection scopesToCollect;
Collection scopesToResolve;
if (dependencyContext.isResolutionRequiredForCurrentProject()) {
scopesToCollect = dependencyContext.getScopesToCollectForCurrentProject();
scopesToResolve = dependencyContext.getScopesToResolveForCurrentProject();
this.lifeCycleDependencyResolver.resolveProjectDependencies(project, scopesToCollect, scopesToResolve, session, aggregating, Collections.emptySet());
dependencyContext.synchronizeWithProjectState();
}
Iterator var8;
MavenProject aggregatedProject;
if (aggregating) {
scopesToCollect = this.toScopes(mojoDescriptor.getDependencyCollectionRequired());
scopesToResolve = this.toScopes(mojoDescriptor.getDependencyResolutionRequired());
if (dependencyContext.isResolutionRequiredForAggregatedProjects(scopesToCollect, scopesToResolve)) {
var8 = session.getProjects().iterator();
while(var8.hasNext()) {
aggregatedProject = (MavenProject)var8.next();
if (aggregatedProject != project) {
// !!!! Starts resolving all projects in current maven session !!!!
this.lifeCycleDependencyResolver.resolveProjectDependencies(aggregatedProject, scopesToCollect, scopesToResolve, session, aggregating, Collections.emptySet());
}
}
}
}
有问题的 Mojo 只是在目标下生成一堆关于一些 Cucumber 测试的报告 html 文件,因此我们决定暂时将其删除,但我想报告此行为,以防它不仅仅是用户错误(这很可能是)。任何见解表示赞赏。
预期:在模块本身构建之前,模块 pom 中的依赖范围不应解析为实际版本。
似乎我太专注于解决问题而无法真正理解聚合器目标的想法。根本原因是前面提到的宁静:聚合目标被绑定到某些模块中的集成测试后生命周期阶段。我后来了解到的是,聚合器目标永远不应该绑定到生命周期阶段,而应该直接从命令行调用。这个想法是只为所有模块的聚合运行一次。我们从多存储库设置转向在单一存储库中构建 Maven 多模块,并且生命周期阶段绑定在迁移之前可能不会引起问题,但现在当该 Maven 项目成为多模块构建的一部分时,会适得其反。