在Maven Central

时间:2016-09-22 11:46:10

标签: java maven

对于Maven central(或任何其他给定的Nexus存储库)上的工件,我想列出所有直接依赖项。

首先,我考虑过只读取pom.xml并从依赖项部分收集所有条目。但我注意到这些条目可能没有版本(由依赖关系管理提供),或者条目可能来自父poms。

我的第二个想法是构建某种人工Maven项目并使用mvn dependency:tree收集依赖项。这可能会变得复杂。

最直接(但也可靠)的方式是什么?

2 个答案:

答案 0 :(得分:5)

在Maven插件之外,您可以使用Aether以编程方式执行此操作。有一种方法readArtifactDescriptor就是这样做的:

  

获取有关工件的信息,例如其直接依赖关系和潜在的重定位。

首先,将Aether依赖项添加到您的POM:

<dependencies>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-impl</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-connector-basic</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-file</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.aether</groupId>
        <artifactId>aether-transport-http</artifactId>
        <version>${aetherVersion}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-aether-provider</artifactId>
        <version>${mavenVersion}</version>
    </dependency>
</dependencies>
<properties>
    <aetherVersion>1.1.0</aetherVersion>
    <mavenVersion>3.3.9</mavenVersion>
</properties>

然后你可以:

public static void main(final String[] args) throws Exception {
    DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
    RepositorySystem system = newRepositorySystem(locator);
    RepositorySystemSession session = newSession(system);

    RemoteRepository central = new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build();

    Artifact artifact = new DefaultArtifact("groupId:artifactId:version");
    ArtifactDescriptorRequest request = new ArtifactDescriptorRequest(artifact, Arrays.asList(central), null);
    ArtifactDescriptorResult result = system.readArtifactDescriptor(session, request);

    for (Dependency dependency : result.getDependencies()) {
        System.out.println(dependency);
    }
}

private static RepositorySystem newRepositorySystem(DefaultServiceLocator locator) {
    locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
    locator.addService(TransporterFactory.class, FileTransporterFactory.class);
    locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
    return locator.getService(RepositorySystem.class);
}

private static RepositorySystemSession newSession(RepositorySystem system) {
    DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
    LocalRepository localRepo = new LocalRepository("target/local-repo");
    session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
    // set possible proxies and mirrors
    session.setProxySelector(new DefaultProxySelector().add(new Proxy(Proxy.TYPE_HTTP, "host", 3625), Arrays.asList("localhost", "127.0.0.1")));
    session.setMirrorSelector(new DefaultMirrorSelector().add("my-mirror", "http://mirror", "default", false, "external:*", null));
    return session;
}

这样做是创建一个Aether存储库系统并告诉它读取给定工件的工件描述符。该工件由构造函数new DefaultArtifact("...")构造,为其提供所需的坐标。

使用此工件和要从中获取它的存储库列表创建请求对象。在上面的示例中,只添加了Maven Central,但您可以使用RemoteRepository类创建更多RemoteRepository.Builder。调用readArtifactDescriptor后,结果包含直接依赖项列表,可以使用getDependencies()检索。

可以分别在DefaultProxySelectorDefaultMirrorSelector的帮助下配置代理和镜像。 DefaultProxySelector.add使用Proxy作为参数,可以使用其构造函数创建它的类型(如"http"),主机,端口和可选的Authentication(取一个查看AuthenticationBuilder类以创建身份验证对象)和非代理主机列表。以同样的方式,DefaultMirrorSelector.add获取其id,URL,类型(Maven为"default",但您可以使用P2),无论是存储库管理器,还是实际存储库ID镜像(根据{{​​3}}),以及未镜像的存储库类型。

答案 1 :(得分:0)

以下工作流程似乎没问题:

  1. 从Maven central下载pom,将其放在一个单独的目录中,并将其命名为pom.xml

  2. 应用mvn dependency:list -DexcludeTransitive并获取控制台输出。

  3. 从控制台输出中过滤依赖项列表。