2016-02-13 278 views
2

我在写一个需要了解给定的org.apache.maven.model.Dependency的传递依赖关系的Maven 3插件。我怎样才能做到这一点?查找Maven依赖项对象的依赖关系

+1

该插件的用途是什么?看看maven-dependency-plugin代码....除此之外,你没有定义mojo上的DependencyResolution? – khmarbaise

+1

你需要的不仅仅是一个'依赖关系'。您需要访问'MavenProject',因为解决的传递依赖依赖于潜在的冲突解决。 – Tunaki

+0

@Tunaki我在Maven 3插件中,所以我也有一个'MavenProject'。 –

回答

1

所以下面的代码应该给你的印象如何做到这一点。

@Mojo(name = "test", requiresDependencyResolution = ResolutionScope.COMPILE, defaultPhase = LifecyclePhase.PACKAGE ...) 
public class TestMojo 
    extends AbstractMojo 
{ 
    @Parameter(defaultValue = "${project}", readonly = true) 
    private MavenProject project; 

    public void execute() 
     throws MojoExecutionException, MojoFailureException 
    { 
     List<Dependency> dependencies = project.getDependencies(); 
     for (Dependency dependency : dependencies) 
     { 
      getLog().info("Dependency: " + getId(dependency)); 
     } 

     Set<Artifact> artifacts = project.getArtifacts(); 
     for (Artifact artifact : artifacts) 
     { 
      getLog().info("Artifact: " + artifact.getId()); 
     } 
    } 

    private String getId(Dependency dep) { 
     StringBuilder sb = new StringBuilder(); 
     sb.append(dep.getGroupId()); 
     sb.append(':'); 
     sb.append(dep.getArtifactId()); 
     sb.append(':'); 
     sb.append(dep.getVersion()); 
     return sb.toString(); 
    } 

} 

上面的代码会给你解决的工件以及依赖关系。您需要在依赖关系之间做出区分(在这种情况下,不需要传递项目依赖项,也不需要传递解决方案的工件)。

最重要的是requiresDependencyResolution = ResolutionScope.COMPILE否则你会得到nullgetArtifacts()

Tunaki的建议将适用于任何不属于您的项目的工件......问题是您真正需要的是什么?

5

在Maven中3,您可以访问所有依赖于基于树的形式,通过依托maven-dependency-tree共享组件:

基于树的API,用于Maven项目依赖的分辨率。

该组件引入了可以为给定的Maven项目构建依赖关系树的DependencyGraphBuilder。您还可以使用ArtifactFilter过滤工件,该工件有几个内置实现可以通过groupId,artifactId(IncludesArtifactFilterExcludesArtifactFilter),作用域(ScopeArtifactFilter)等进行过滤。如果过滤器为null,则保留所有依赖关系。

对于您的情况,由于您定位了特定的工件,因此可以使用工件的模式groupId:artifactId添加IncludesArtifactFilter。示例代码为:

@Mojo(name = "foo") 
public class MyMojo extends AbstractMojo { 

    @Parameter(defaultValue = "${project}", readonly = true, required = true) 
    private MavenProject project; 

    @Parameter(defaultValue = "${session}", readonly = true, required = true) 
    private MavenSession session; 

    @Component(hint = "default") 
    private DependencyGraphBuilder dependencyGraphBuilder; 

    public void execute() throws MojoExecutionException, MojoFailureException { 
     ArtifactFilter artifactFilter = new IncludesArtifactFilter(Arrays.asList("groupId:artifactId")); 
     ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); 
     buildingRequest.setProject(project); 
     try { 
      DependencyNode rootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, artifactFilter); 
      CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor(); 
      rootNode.accept(visitor); 
      for (DependencyNode node : visitor.getNodes()) { 
       System.out.println(node.toNodeString()); 
      } 
     } catch (DependencyGraphBuilderException e) { 
      throw new MojoExecutionException("Couldn't build dependency graph", e); 
     } 
    } 

} 

这可以访问依赖关系树的根节点,即当前项目。从该节点,您可以通过调用getChildren()方法来访问所有孩子。所以如果你想列出所有的依赖关系,你可以递归地遍历该图。该组件确实为CollectingDependencyNodeVisitor提供了一个工具。它会将所有依赖关系收集到List中以轻松循环。

对于Maven插件,下面的依赖性因此,有必要:

<dependency> 
    <groupId>org.apache.maven.shared</groupId> 
    <artifactId>maven-dependency-tree</artifactId> 
    <version>3.0</version> 
</dependency> 
+1

尽管它没有使用Dependency类,但使用了DependencyNode类,但该示例完全符合我的要求,因此应该是可接受的答案。 – codewing