I'm writing a Maven 3 plugin that needs to know the transitive dependencies of a given org.apache.maven.model.Dependency
. How can I do that?

- 37,506
- 41
- 139
- 175
-
1What is the purpose of the plugin? Take a look into maven-dependency-plugin code....Apart from that didn't you define the DependencyResolution on the mojo ? – khmarbaise Feb 13 '16 at 11:22
-
1You need more than a `Dependency`. You need access to the `MavenProject` since the resolved transitive dependencies depends on potential conflict resolution. – Tunaki Feb 13 '16 at 11:36
-
@Tunaki I'm in a Maven 3 plugin, so I have a `MavenProject`, too. – Dan Fabulich Feb 13 '16 at 12:08
-
@khmarbaise That code is all [deprecated in Maven 3](http://stackoverflow.com/questions/1492000/how-to-get-access-to-mavens-dependency-hierarchy-within-a-plugin). :-( – Dan Fabulich Feb 13 '16 at 12:09
-
1By the way, do you want all resolved dependencies, all dependencies (including excluded one), dependencies before or after conflict resolution? – Tunaki Feb 13 '16 at 12:16
-
1@DanFabulich First you didn't answer my questions..Apart from that what code is exactly deprecated? Usually a plugin is always in the context of a project ... – khmarbaise Feb 13 '16 at 13:16
2 Answers
In Maven 3, you access all dependencies in a tree-based form by relying on the maven-dependency-tree
shared component:
A tree-based API for resolution of Maven project dependencies.
This component introduces the DependencyGraphBuilder
that can build the dependency tree for a given Maven project. You can also filter artifacts with a ArtifactFilter
, that has a couple of built-in implementations to filter by groupId, artifactId (IncludesArtifactFilter
and ExcludesArtifactFilter
), scope (ScopeArtifactFilter
), etc. If the fiter is null
, all dependencies are kept.
In your case, since you target a specific artifact, you could add a IncludesArtifactFilter
with the pattern groupId:artifactId
of your artifact. A sample code would be:
@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);
}
}
}
This gives access to the root node of the dependency tree, which is the current project. From that node, you can access all chidren by calling the getChildren()
method. So if you want to list all dependencies, you can traverse that graph recursively. This component does provide a facility for doing that with the CollectingDependencyNodeVisitor
. It will collect all dependencies into a List
to easily loop through it.
For the Maven plugin, the following dependency is therefore necessary:
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-tree</artifactId>
<version>3.0</version>
</dependency>

- 132,869
- 46
- 340
- 423
-
1Even though it is not utilizing the Dependency class but the DependencyNode class the example did exactly what I was looking for and should thus be the accepted answer. – codewing Sep 20 '17 at 15:32
So the following code should give you an impression how to do it.
@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();
}
}
The above code will give you the resolved artifacts as well as dependencies. You need to make a difference between the dependencies (in this case the project dependencies without transitive and the artifacts which are the solved artifacts incl. transitive.).
Most important is requiresDependencyResolution = ResolutionScope.COMPILE
otherwise you will get null
for getArtifacts()
.
The suggestion by Tunaki will work for any kind of artifact which is not part of your project...The question is what you really need?

- 92,914
- 28
- 189
- 235