代码之家  ›  专栏  ›  技术社区  ›  javamonkey79

Maven:如何在MOJO中以编程方式获取所有可传递依赖项[复制]

  •  3
  • javamonkey79  · 技术社区  · 15 年前

    0 回复  |  直到 11 年前
        1
  •  29
  •   mkobit    9 年前

    依赖插件具有 tree goal MavenProject 使用 DependencyTreeBuilder ,这将返回 DependencyNode 具有有关已解析依赖项(及其可传递依赖项)的层次结构信息。

    您可以直接从TreeMojo复制大部分代码。它使用 CollectingDependencyNodeVisitor 穿过这棵树 List

    您可以访问 Artifact 通过调用 getArtifact() ,然后根据需要获取工件信息。为了得到排除原因, 从属节点 有一个 getState() 方法,该方法返回一个int,指示是否包含依赖项,或者如果不包含,则返回省略依赖项的原因是什么(DependencyNode类中有常量可用于检查返回值)

    //All components need this annotation, omitted for brevity
    
    /**
     * @component
     * @required
     * @readonly
     */
    private ArtifactFactory artifactFactory;
    private ArtifactMetadataSource artifactMetadataSource;
    private ArtifactCollector artifactCollector;
    private DependencyTreeBuilder treeBuilder;
    private ArtifactRepository localRepository;
    private MavenProject project;
    
    public void execute() throws MojoExecutionException, MojoFailureException {
        try {
            ArtifactFilter artifactFilter = new ScopeArtifactFilter(null);
    
            DependencyNode rootNode = treeBuilder.buildDependencyTree(project,
                    localRepository, artifactFactory, artifactMetadataSource,
                    artifactFilter, artifactCollector);
    
            CollectingDependencyNodeVisitor visitor = 
                new CollectingDependencyNodeVisitor();
    
            rootNode.accept(visitor);
    
            List<DependencyNode> nodes = visitor.getNodes();
            for (DependencyNode dependencyNode : nodes) {
                int state = dependencyNode.getState();
                Artifact artifact = dependencyNode.getArtifact();
                if(state == DependencyNode.INCLUDED) {                    
                    //...
                } 
            }
        } catch (DependencyTreeBuilderException e) {
            // TODO handle exception
            e.printStackTrace();
        }
    }
    
        2
  •  20
  •   mkobit    9 年前

    你可以用 MavenProject#getDependencyArtifacts() MavenProject#getDependencies() (后者也返回可传递依赖项)。

    /**
     * Test Mojo
     *
     * @goal test
     * @requiresDependencyResolution compile
     */
    public class TestMojo extends AbstractMojo {
    
        /**
         * The Maven Project.
         *
         * @parameter expression="${project}"
         * @required
         * @readonly
         */
        private MavenProject project = null;
    
        /**
         * Execute Mojo.
         *
         * @throws MojoExecutionException If an error occurs.
         * @throws MojoFailureException If an error occurs.
         */
        public void execute() throws MojoExecutionException,
    MojoFailureException {
    
            ...
    
            Set dependencies = project.getDependencies();
    
           ...
        }
    
    }
    

    我不完全确定,但我认为两种方法都返回 Artifact 为groupId、artifactId、version等公开getter的实现。

        3
  •  14
  •   Lukas Eder    7 年前

    下面是一个最新的Maven3示例,说明如何获取所有依赖项(包括可传递的)以及如何访问文件本身(例如,如果需要将路径添加到类路径)。

    // Default phase is not necessarily important.
    // Both requiresDependencyCollection and requiresDependencyResolution are extremely important however!
    @Mojo(name = "simple", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
    public class SimpleMojo extends AbstractMojo {
      @Parameter(defaultValue = "${project}", readonly = true)
      private MavenProject mavenProject;
    
      @Override
      public void execute() throws MojoExecutionException, MojoFailureException {
        for (final Artifact artifact : mavenProject.getArtifacts()) {
          // Do whatever you need here.
          // If having the actual file (artifact.getFile()) is not important, you do not need requiresDependencyResolution.
        }
      }
    }
    

    @Parameter(defaultValue = "${project.compileClasspathElements}", readonly = true, required = true)
    private List<String> compilePath;
    

    将requiresDependencyCollection和requiresDependencyResolution更改为不同的值将允许您更改要获取的内容的范围。这个 maven documentation

        4
  •  5
  •   mkobit    9 年前

    尝试使用 Aether jcabi-aether 要获取任何项目的所有依赖项的列表,请执行以下操作:

    File repo = this.session.getLocalRepository().getBasedir();
    Collection<Artifact> deps = new Aether(this.getProject(), repo).resolve(
      new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
      JavaScopes.RUNTIME
    );
    
        5
  •  3
  •   kane    9 年前

    为什么不收回所有依赖项(直接依赖项和传递依赖项)并检查排除情况呢?

    @Parameter(property = "project", required = true, readonly = true)
    private MavenProject project;
    
    public void execute() throws MojoExecutionException
    {
      for (Artifact a : project.getArtifacts()) {
        if( a.getScope().equals(Artifact.SCOPE_TEST) ) { ... }
        if( a.getScope().equals(Artifact.SCOPE_PROVIDED) ) { ... }
        if( a.getScope().equals(Artifact.SCOPE_RUNTIME) ) { ... }
      }
    }
    
        7
  •  1
  •   Lukas Eder    7 年前

    对于Maven 3,您可以使用DependencyGraphBuilder。它和DependencyTreeBuilder做的事情几乎相同。

    下面是一个例子

        import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
        import org.apache.maven.artifact.resolver.filter.IncludesArtifactFilter;
        import org.apache.maven.execution.MavenSession;
        import org.apache.maven.model.Dependency;
        import org.apache.maven.plugins.annotations.ResolutionScope;
        import org.apache.maven.plugins.annotations.LifecyclePhase;
        import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
    
        import org.apache.maven.shared.dependency.graph.DependencyNode;
        import org.apache.maven.shared.dependency.graph.traversal.CollectingDependencyNodeVisitor;
    
        public class AnanlyzeTransitiveDependencyMojo extends AbstractMojo{
    
            @Parameter(defaultValue = "${project}", readonly = true, required = true)
            private MavenProject project;
    
            @Parameter(defaultValue = "${session}", readonly = true, required = true)
            private MavenSession session;
    
            @Component(hint="maven3")
            private DependencyGraphBuilder dependencyGraphBuilder;
    
            @Override
            public void execute() throws MojoExecutionException, MojoFailureException {
        // If you want to filter out certain dependencies.
                 ArtifactFilter artifactFilter = new IncludesArtifactFilter("groupId:artifactId:version");
                 ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
                 buildingRequest.setProject(project);
                try{
                   DependencyNode depenGraphRootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, artifactFilter);
                   CollectingDependencyNodeVisitor visitor = new  CollectingDependencyNodeVisitor();
                   depenGraphRootNode.accept(visitor);
                   List<DependencyNode> children = visitor.getNodes();
    
                   getLog().info("CHILDREN ARE :");
                   for(DependencyNode node : children) {
                       Artifact atf = node.getArtifact();
                }
    }catch(Exception e) {
        e.printStackTrace();
    }