Pergunta

In a Maven 2 mojo you can use something like this to get the dependency tree:

DependencyNode rootNode;
try {
  rootNode = treeBuilder.buildDependencyTree(project, localRepository,
      artifactFactory, artifactMetadataSource, null, artifactCollector);
} catch (DependencyTreeBuilderException e) {
  throw new MojoExecutionException("Failed to create dependency tree.", e);
}
final CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor();
rootNode.accept(visitor);
final List<DependencyNode> nodes = visitor.getNodes();

What's the Maven 3 equivalent? Many involved classes have become deprecated in the meantime (ArtifactCollector, ArtifactMetadataSource, etc.).

Foi útil?

Solução

Maven 3 uses Aether for dependency resolution. Near the bottom of the docs is another link to using Aether in Maven plugins.

Outras dicas

You need to use Aether (this is what Maven 3 is using). I'd recommend to use a simple wrapper around it, called jcabi-aether (I'm a developer of it).

I haven't found any working solution online, so I looked into the Maven source code and worked out a solution myself. Most of the following code was copied from maven source code, I have tested it with Maven 3.5.4 and it worked perfectly.

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.DefaultDependencyResolutionRequest;
import org.apache.maven.project.DependencyResolutionResult;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectDependenciesResolver;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.util.filter.AndDependencyFilter;
import org.eclipse.aether.util.filter.ScopeDependencyFilter;

import javax.inject.Inject;
import java.util.*;

@Mojo( name = "test-mojo", requiresDependencyResolution = ResolutionScope.RUNTIME)
public class TestMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;
    @Parameter(defaultValue = "${session}", readonly = true, required = true)
    private MavenSession session;
    @Inject
    private ProjectDependenciesResolver dependenciesResolver;

    public void execute() throws MojoExecutionException {
        try {
            Collection<String> scopesToResolve = new HashSet<>();
            scopesToResolve.add("compile");
            scopesToResolve.add("provided");
            scopesToResolve.add("runtime");
            scopesToResolve.add("system");
            scopesToResolve.add("test");
            Collection<String> scopesToCollect = new HashSet<>();
            scopesToCollect.add("compile");
            scopesToCollect.add("provided");
            scopesToCollect.add("runtime");
            scopesToCollect.add("system");
            scopesToCollect.add("test");
            Collection<Artifact> projectArtifacts = new HashSet<>();
            projectArtifacts.add(project.getArtifact());
            DependencyFilter collectionFilter = new ScopeDependencyFilter( null, negate( scopesToCollect ) );
            DependencyFilter resolutionFilter = new ScopeDependencyFilter( null, negate( scopesToResolve ) );
            resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, resolutionFilter );
            resolutionFilter = AndDependencyFilter.newInstance( resolutionFilter, new ReactorDependencyFilter( projectArtifacts ) );
            DefaultDependencyResolutionRequest request =
                    new DefaultDependencyResolutionRequest( project, session.getRepositorySession() );
            request.setResolutionFilter( resolutionFilter );
            DependencyResolutionResult result = dependenciesResolver.resolve( request );

            // Here is your dependency gragh, you can do whatever you want with it.
            List<DependencyNode> children = result.getDependencyGraph().getChildren();
            List<DependencyNode> grandChildren = children.get(0).getChildren();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MojoExecutionException(e.getMessage());
        }
    }

    private Collection<String> negate( Collection<String> scopes )
    {
        Collection<String> result = new HashSet<>();
        Collections.addAll( result, "system", "compile", "provided", "runtime", "test" );

        for ( String scope : scopes )
        {
            if ( "compile".equals( scope ) )
            {
                result.remove( "compile" );
                result.remove( "system" );
                result.remove( "provided" );
            }
            else if ( "runtime".equals( scope ) )
            {
                result.remove( "compile" );
                result.remove( "runtime" );
            }
            else if ( "compile+runtime".equals( scope ) )
            {
                result.remove( "compile" );
                result.remove( "system" );
                result.remove( "provided" );
                result.remove( "runtime" );
            }
            else if ( "runtime+system".equals( scope ) )
            {
                result.remove( "compile" );
                result.remove( "system" );
                result.remove( "runtime" );
            }
            else if ( "test".equals( scope ) )
            {
                result.clear();
            }
        }

        return result;
    }
    private static class ReactorDependencyFilter
            implements DependencyFilter
    {

        private Set<String> keys = new HashSet<>();

        ReactorDependencyFilter( Collection<Artifact> artifacts )
        {
            for ( Artifact artifact : artifacts )
            {
                String key = ArtifactUtils.key( artifact );
                keys.add( key );
            }
        }

        public boolean accept(DependencyNode node, List<DependencyNode> parents )
        {
            org.eclipse.aether.graph.Dependency dependency = node.getDependency();
            if ( dependency != null )
            {
                org.eclipse.aether.artifact.Artifact a = dependency.getArtifact();
                String key = ArtifactUtils.key( a.getGroupId(), a.getArtifactId(), a.getVersion() );
                return !keys.contains( key );
            }
            return false;
        }

    }
}

Also, notice that you need to add some dependencies to make it work. Here is mine.

<dependencies>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-plugin-api</artifactId>
        <version>3.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.plugin-tools</groupId>
        <artifactId>maven-plugin-annotations</artifactId>
        <version>3.6.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-project</artifactId>
        <version>2.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven.shared</groupId>
        <artifactId>maven-common-artifact-filters</artifactId>
        <version>3.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-core</artifactId>
        <version>3.5.4</version>
    </dependency>
</dependencies>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top