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

如何配置Maven Artifact Resolver实现传递依赖列表输出?

解决Maven依赖解析中"local repository manager cannot be null"异常的方案

你的代码缺少LocalRepositoryManager初始化、RepositorySystem正确实例化以及远程仓库配置等关键环节,以下是基于你使用的依赖版本(Apache Maven Model v4.0.0-alpha-2、Maven Artifact Resolver v1.8.2)的完整可行方案:

1. 确保依赖配置正确

首先在项目的pom.xml中补充必要依赖(缺少的连接器和传输组件是远程依赖拉取的核心):

<dependencies>
    <!-- Maven Model -->
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-model</artifactId>
        <version>4.0.0-alpha-2</version>
    </dependency>
    <!-- Maven Artifact Resolver核心 -->
    <dependency>
        <groupId>org.apache.maven.resolver</groupId>
        <artifactId>maven-resolver-api</artifactId>
        <version>1.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.resolver</groupId>
        <artifactId>maven-resolver-impl</artifactId>
        <version>1.8.2</version>
    </dependency>
    <!-- 依赖拉取的连接器与传输组件 -->
    <dependency>
        <groupId>org.apache.maven.resolver</groupId>
        <artifactId>maven-resolver-connector-basic</artifactId>
        <version>1.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.resolver</groupId>
        <artifactId>maven-resolver-transport-file</artifactId>
        <version>1.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.resolver</groupId>
        <artifactId>maven-resolver-transport-http</artifactId>
        <version>1.8.2</version>
    </dependency>
    <!-- 用于完整解析POM(处理父POM、依赖管理等) -->
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-model-builder</artifactId>
        <version>4.0.0-alpha-2</version>
    </dependency>
</dependencies>

2. 完整的依赖解析代码

替换你原有的main方法,以下是包含所有必要配置的实现:

import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultModelBuilder;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelBuildingResult;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.CollectResult;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.util.repository.DefaultMirrorSelector;
import org.eclipse.aether.util.repository.DefaultProxySelector;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class MavenDependencyResolver {

    private static RepositorySystem newRepositorySystem() {
        // 必须通过ServiceLocator获取RepositorySystem实例,不能直接new
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService(RepositorySystem.class, org.eclipse.aether.internal.impl.DefaultRepositorySystem.class);
        return locator.getService(RepositorySystem.class);
    }

    private static RepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
        RepositorySystemSession session = MavenRepositorySystemUtils.newSession();

        // 配置本地仓库:指向用户目录下的.m2/repository
        String localRepoPath = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository";
        LocalRepository localRepo = new LocalRepository(localRepoPath);
        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));

        // 配置镜像与代理(可根据公司Maven settings.xml扩展)
        session.setMirrorSelector(new DefaultMirrorSelector());
        session.setProxySelector(new DefaultProxySelector());

        return session;
    }

    private static List<RemoteRepository> newRepositories(RepositorySystem system, RepositorySystemSession session) {
        List<RemoteRepository> repos = new ArrayList<>();
        // 添加Maven中央仓库,也可从settings.xml读取内部镜像
        repos.add(new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2/").build());
        return repos;
    }

    // 将Maven Model的Dependency转换为Aether的Artifact
    private static Artifact toArtifact(Dependency dependency) {
        return new DefaultArtifact(
                dependency.getGroupId(),
                dependency.getArtifactId(),
                dependency.getClassifier(),
                dependency.getType(),
                dependency.getVersion()
        );
    }

    public static void main(String[] args) throws Exception {
        // 1. 读取并构建完整的POM模型(处理父POM、依赖管理等逻辑)
        File pomFile = new File("C:\\Users\\lc70844\\eclipse-workspace\\test\\pom.xml");
        MavenXpp3Reader reader = new MavenXpp3Reader();
        Model rawModel = reader.read(new FileReader(pomFile));

        DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
        DefaultModelBuildingRequest buildingRequest = new DefaultModelBuildingRequest();
        buildingRequest.setModel(rawModel);
        buildingRequest.setPomFile(pomFile);
        ModelBuildingResult buildingResult = modelBuilder.build(buildingRequest);
        Model model = buildingResult.getEffectiveModel();

        // 2. 初始化RepositorySystem和Session
        RepositorySystem system = newRepositorySystem();
        RepositorySystemSession session = newRepositorySystemSession(system);
        List<RemoteRepository> remoteRepos = newRepositories(system, session);

        // 3. 解析每个依赖(含传递依赖)
        for (Dependency dependency : model.getDependencies()) {
            System.out.println("=== 解析依赖:" + dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion() + " ===");

            // 创建收集请求获取完整依赖树
            CollectRequest collectRequest = new CollectRequest();
            collectRequest.setRoot(new org.eclipse.aether.graph.Dependency(toArtifact(dependency), dependency.getScope()));
            collectRequest.setRepositories(remoteRepos);

            CollectResult collectResult = system.collectDependencies(session, collectRequest);

            // 解析收集到的依赖
            DependencyRequest dependencyRequest = new DependencyRequest(collectResult.getRoot(), null);
            DependencyResult dependencyResult = system.resolveDependencies(session, dependencyRequest);

            // 打印解析结果
            dependencyResult.getArtifactResults().stream()
                    .map(result -> result.getArtifact())
                    .map(artifact -> artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion())
                    .forEach(System.out::println);
        }
    }
}

关键修正说明

  • RepositorySystem实例化:必须通过DefaultServiceLocator加载实现类,不能直接new DefaultRepositorySystem,这是Aether的规范要求。
  • LocalRepositoryManager配置:通过System.getProperty("user.home")动态获取用户目录,自动指向.m2/repository,避免硬编码路径。
  • 完整POM解析:使用maven-model-builder构建有效模型,确保处理父POM继承、dependencyManagement覆盖等逻辑,避免原始POM信息不全的问题。
  • 依赖流程规范:先通过collectDependencies获取完整依赖树,再通过resolveDependencies解析实际文件,这是Aether的标准流程。

优化方案:一次性解析全项目依赖树

如果需要获取整个项目的完整依赖树(含传递依赖),可以直接以项目自身为根节点,效率更高:

// 替换main方法中的循环部分
DefaultArtifact projectArtifact = new DefaultArtifact(
        model.getGroupId(),
        model.getArtifactId(),
        model.getPackaging(),
        model.getVersion()
);
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRoot(new org.eclipse.aether.graph.Dependency(projectArtifact, "compile"));
collectRequest.setRepositories(remoteRepos);

CollectResult collectResult = system.collectDependencies(session, collectRequest);
DependencyRequest dependencyRequest = new DependencyRequest(collectResult.getRoot(), null);
DependencyResult dependencyResult = system.resolveDependencies(session, dependencyRequest);

// 打印树形结构的依赖
printDependencyTree(dependencyResult.getRoot(), 0);

// 添加打印依赖树的工具方法
private static void printDependencyTree(DependencyNode node, int depth) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
Artifact artifact = node.getArtifact();
System.out.println(indent + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion());
for (DependencyNode child : node.getChildren()) {
printDependencyTree(child, depth + 1);
}
}

内容的提问来源于stack exchange,提问作者Cardinal System
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:30:46