MavenProject.getArtifacts()跨模块调用返回依赖列表不一致问题
我之前也踩过这个Maven插件的坑,太懂这种明明单独跑没问题,整项目构建就出岔子的郁闷了!咱们来拆解下原因和解决办法:
问题根源:Maven构建上下文的差异
当你单独执行模块的mvn clean package时,Maven会为这个模块完整执行依赖解析全流程:从本地仓库找依赖、远程仓库下载缺失的依赖、处理依赖传递和冲突,最终mavenProject.getArtifacts()能拿到该模块所有直接+间接的依赖(包括不同scope的)。
但在整个项目的Reactor构建中,情况就不一样了:
- Maven会按照模块间的依赖关系排序执行,上游模块可能还没完成
install,当前模块只能拿到上游模块的临时构建产物,而非正式发布的artifact - Reactor模式下Maven会做优化,只解析当前构建阶段需要的依赖(比如绑定到
compile阶段的话,testscope的依赖可能不会被包含) - 如果你的插件绑定到了过早的生命周期阶段(比如
validate或initialize),此时依赖还没完成完整解析,getArtifacts()自然拿不到全量集合
解决办法
1. 把插件绑定到正确的生命周期阶段
确保插件在依赖完全解析之后执行,比如process-classes或package阶段,这样Maven已经完成了所有依赖的解析工作。
在模块的pom.xml里配置:
<build> <plugins> <plugin> <groupId>你的插件GroupId</groupId> <artifactId>你的插件ArtifactId</artifactId> <version>插件版本</version> <executions> <execution> <!-- 选择合适的阶段,process-classes是比较安全的选择 --> <phase>process-classes</phase> <goals> <goal>你的插件目标</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
2. 主动构建依赖图,而非直接依赖getArtifacts()
mavenProject.getArtifacts()的返回结果受构建上下文影响很大,更可靠的方式是用Maven Shared Components里的DependencyGraphBuilder主动构建完整的依赖树,这样无论单独还是整体构建,都能拿到全量依赖。
在你的Mojo类中实现:
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; import org.apache.maven.shared.dependency.graph.DependencyNode; import org.apache.maven.execution.MavenSession; import java.util.HashSet; import java.util.Set; @Mojo(name = "your-goal") public class YourMojo extends AbstractMojo { @Parameter(defaultValue = "${project}", readonly = true) private MavenProject mavenProject; @Parameter(defaultValue = "${session}", readonly = true) private MavenSession session; @Component private DependencyGraphBuilder dependencyGraphBuilder; @Override public void execute() throws MojoExecutionException { try { // 构建完整的依赖图 DependencyNode rootNode = dependencyGraphBuilder.buildDependencyGraph( new org.apache.maven.shared.dependency.graph.DependencyGraphRequest( mavenProject, session.getRepositorySession() ) ); // 遍历依赖图收集所有artifact Set<org.apache.maven.artifact.Artifact> allArtifacts = new HashSet<>(); collectAllArtifacts(rootNode, allArtifacts); // 这里allArtifacts就是你需要的全量依赖集合了 getLog().info("Total artifacts collected: " + allArtifacts.size()); } catch (DependencyGraphBuilderException e) { throw new MojoExecutionException("Failed to build dependency graph", e); } } private void collectAllArtifacts(DependencyNode node, Set<org.apache.maven.artifact.Artifact> artifacts) { artifacts.add(node.getArtifact()); // 递归遍历子节点 for (DependencyNode child : node.getChildren()) { collectAllArtifacts(child, artifacts); } } }
3. 检查项目聚合/继承的依赖配置
如果你的项目有父pom或聚合pom,要确认:
- 当前模块的依赖scope没有被父pom意外覆盖(比如父pom把某个依赖设为
test,子模块没调整,导致整体构建时该依赖不会出现在compile阶段的依赖集合里) - 聚合pom里没有排除当前模块的某些依赖,或者配置了特殊的依赖管理规则
4. 尝试使用getDependencyArtifacts()替代
如果只是需要直接依赖的集合,可以试试mavenProject.getDependencyArtifacts(),这个方法专门返回项目的依赖artifact集合,比getArtifacts()更聚焦,但同样要注意生命周期阶段的问题。
内容的提问来源于stack exchange,提问作者tbeernot
相关产品推荐
相关产品推荐

