You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MavenProject.getArtifacts()跨模块调用返回依赖列表不一致问题

我之前也踩过这个Maven插件的坑,太懂这种明明单独跑没问题,整项目构建就出岔子的郁闷了!咱们来拆解下原因和解决办法:

问题根源:Maven构建上下文的差异

当你单独执行模块的mvn clean package时,Maven会为这个模块完整执行依赖解析全流程:从本地仓库找依赖、远程仓库下载缺失的依赖、处理依赖传递和冲突,最终mavenProject.getArtifacts()能拿到该模块所有直接+间接的依赖(包括不同scope的)。

但在整个项目的Reactor构建中,情况就不一样了:

  • Maven会按照模块间的依赖关系排序执行,上游模块可能还没完成install,当前模块只能拿到上游模块的临时构建产物,而非正式发布的artifact
  • Reactor模式下Maven会做优化,只解析当前构建阶段需要的依赖(比如绑定到compile阶段的话,test scope的依赖可能不会被包含)
  • 如果你的插件绑定到了过早的生命周期阶段(比如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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:27:26