以太,如何获得与层次结构的依赖关系

时间:2016-01-31 20:50:11

标签: java maven aether

我正在使用eather重新创建相同的maven依赖结构:我的代码中的树。 根据文档,我发现这个有用的example正确地列出了与插件相同的depdendencys,但它没有任何“树”信息,它只是一个单独的列表。

 public static void main( String[] args )
    throws Exception
{
    System.out.println( "------------------------------------------------------------" );
    System.out.println( ResolveTransitiveDependencies.class.getSimpleName() );

    RepositorySystem system = Booter.newRepositorySystem();

    RepositorySystemSession session = Booter.newRepositorySystemSession( system );

    Artifact artifact = new DefaultArtifact( "org.eclipse.aether:aether-impl:1.0.0.v20140518" );

    DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter( JavaScopes.COMPILE );

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot( new Dependency( artifact, JavaScopes.COMPILE ) );
    collectRequest.setRepositories( Booter.newRepositories( system, session ) );

    DependencyRequest dependencyRequest = new DependencyRequest( collectRequest, classpathFlter );

    List<ArtifactResult> artifactResults =
        system.resolveDependencies( session, dependencyRequest ).getArtifactResults();

    for ( ArtifactResult artifactResult : artifactResults )
    {
        System.out.println( artifactResult.getArtifact() + " resolved to " + artifactResult.getArtifact().getFile() );
    }
}

然后我编写了另一段代码来检索非传递依赖项,并且反复调用它,能够获得完整的依赖图,但没有任何限制,所以我应该实现一些过滤/限制例程。

由于我想尽可能保持相同的插件逻辑,而不引入“我的”过滤,是否有任何方法可以调整第一个示例以便检索层次结构信息?

1 个答案:

答案 0 :(得分:3)

如果您想要exactly the same行为,就像插件实现一样,我建议您查看插件的源代码here,这样您就不会错过任何细微差别。但基本方法是使用collectRequestcollectDependencies,如下所示:

public static void main(String[] args) throws Exception {
    System.out.println("------------------------------------------------------------");

    RepositorySystem system = Booter.newRepositorySystem();

    RepositorySystemSession session = Booter.newRepositorySystemSession(system);

    Artifact artifact = new DefaultArtifact("org.apache.maven.plugins:maven-shade-plugin:2.3");

    DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
    collectRequest.setRepositories(Booter.newRepositories(system, session));

    DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, classpathFlter);

    List<ArtifactResult> artifactResults =
            system.resolveDependencies(session, dependencyRequest).getArtifactResults();

//        for (ArtifactResult artifactResult : artifactResults) {
//            System.out.println(artifactResult.getArtifact() + " resolved to " + artifactResult.getArtifact().getFile());
//        }

    //use collectDependencies to collect
    CollectResult collectResult = system.collectDependencies(session, collectRequest);
    DependencyNode node = collectResult.getRoot();
    node.accept(new TreeDependencyVisitor(new DependencyVisitor() {
        String indent = "";
        @Override
        public boolean visitEnter(DependencyNode dependencyNode) {
            System.out.println(indent + dependencyNode.getArtifact());
            indent += "    ";
            return true;
        }

        @Override
        public boolean visitLeave(DependencyNode dependencyNode) {
            indent = indent.substring(0, indent.length() - 4);
            return true;
        }
    }));

}

[编辑:] 要包含测试依赖项,您需要自定义会话的depSelector,如下所示:

    DependencySelector depFilter =
            new AndDependencySelector(
                    new ScopeDependencySelector( "provided" ),
                    new OptionalDependencySelector(),
                    new ExclusionDependencySelector()
            );

将classpathFilter添加到遍历:

DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.TEST);

node.accept(new TreeDependencyVisitor(new FilteringDependencyVisitor(new DependencyVisitor() {
    ...
}, classpathFlter)));

尽管如此,这并不完全与dependency:tree完全相同,因为它实际上会列出所有的jar,它们将用于测试类路径。但有了这个,您实际上可以进一步自定义NodeVisitor以过滤您想要的任何内容。