You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2022/12/11 17:41:38 UTC

[maven-enforcer] branch feature/remove-m-dependency-tree created (now dca987c)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch feature/remove-m-dependency-tree
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git


      at dca987c  WIP use Aether API

This branch includes the following new commits:

     new dca987c  WIP use Aether API

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-enforcer] 01/01: WIP use Aether API

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/remove-m-dependency-tree
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git

commit dca987c33db9768e3f099f59d16df767c7f07136
Author: Konrad Windszus <ko...@netcentric.biz>
AuthorDate: Fri Dec 9 11:17:07 2022 +0100

    WIP use Aether API
---
 enforcer-rules/pom.xml                             |  16 ---
 .../plugins/enforcer/AbstractBanDependencies.java  | 127 ++++++++++-----------
 .../enforcer/BanTransitiveDependencies.java        |  29 +----
 .../maven/plugins/enforcer/BannedPlugins.java      |   4 +-
 .../plugins/enforcer/DependencyConvergence.java    |  26 ++---
 .../plugins/enforcer/utils/ArtifactUtils.java      |  14 ++-
 .../ConflictingDependencyVersionCollector.java     |  49 ++++++++
 .../enforcer/utils/DependencyVersionMap.java       |   1 +
 .../plugins/enforcer/utils/ResolverHelper.java     | 117 +++++++++++++++++++
 pom.xml                                            |   5 -
 10 files changed, 257 insertions(+), 131 deletions(-)

diff --git a/enforcer-rules/pom.xml b/enforcer-rules/pom.xml
index a974cd4..f380035 100644
--- a/enforcer-rules/pom.xml
+++ b/enforcer-rules/pom.xml
@@ -112,22 +112,6 @@
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.maven.shared</groupId>
-      <artifactId>maven-dependency-tree</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.eclipse.aether</groupId>
-          <artifactId>aether-util</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <!-- needed for ArtifactCollector and maven-dependency-tree 2.2 -->
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-compat</artifactId>
-      <scope>compile</scope>
-    </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/AbstractBanDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/AbstractBanDependencies.java
index 4148c6f..a7f9283 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/AbstractBanDependencies.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/AbstractBanDependencies.java
@@ -1,5 +1,4 @@
 package org.apache.maven.plugins.enforcer;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,23 +18,22 @@ package org.apache.maven.plugins.enforcer;
  * under the License.
  */
 
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
-import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.plugins.enforcer.utils.ArtifactUtils;
-import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.plugins.enforcer.utils.ResolverHelper;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-
-import java.util.HashSet;
-import java.util.Set;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
 
 /**
  * Abstract Rule for banning dependencies.
@@ -49,7 +47,7 @@ public abstract class AbstractBanDependencies
     /** Specify if transitive dependencies should be searched (default) or only look at direct dependencies. */
     private boolean searchTransitive = true;
 
-    private transient DependencyGraphBuilder graphBuilder;
+    private transient ResolverHelper resolverHelper;
 
     @Override
     public void execute( EnforcerRuleHelper helper )
@@ -58,41 +56,20 @@ public abstract class AbstractBanDependencies
         MavenProject project;
         try
         {
-            project = (MavenProject) helper.evaluate( "${project}" );
+            project = (MavenProject) Objects.requireNonNull( helper.evaluate( "${project}" ), "${project} is null" );
         }
         catch ( ExpressionEvaluationException eee )
         {
             throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", eee );
         }
 
-        MavenSession session;
-        try
-        {
-            session = (MavenSession) helper.evaluate( "${session}" );
-        }
-        catch ( ExpressionEvaluationException eee )
-        {
-            throw new EnforcerRuleException( "Unable to retrieve the reactor MavenProject: ", eee );
-        }
-
-        try
-        {
-            graphBuilder = helper.getComponent( DependencyGraphBuilder.class );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new EnforcerRuleException( "Unable to lookup DependencyGraphBuilder: ", e );
-        }
-        
-        ProjectBuildingRequest buildingRequest =
-            new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
-        buildingRequest.setProject( project );
+        resolverHelper = new ResolverHelper ( helper );
 
         // get the correct list of dependencies
-        Set<Artifact> dependencies = getDependenciesToCheck( helper, buildingRequest );
+        Map<Artifact, DependencyNode> dependencies = getDependenciesToCheck( helper, project );
 
         // look for banned dependencies
-        Set<Artifact> foundExcludes = checkDependencies( dependencies, helper.getLog() );
+        Set<Artifact> foundExcludes = checkDependencies( dependencies.keySet(), helper.getLog() );
 
         // if any are found, fail the check but list all of them
         if ( foundExcludes != null && !foundExcludes.isEmpty() )
@@ -107,12 +84,37 @@ public abstract class AbstractBanDependencies
             for ( Artifact artifact : foundExcludes )
             {
                 buf.append( getErrorMessage( artifact ) );
+                if ( dependencies.get(artifact) != null )
+                {
+                    // emit location information
+                }
+                
             }
+            // TODO: better location message
+            
             message = buf.toString() + "Use 'mvn dependency:tree' to locate the source of the banned dependencies.";
 
             throw new EnforcerRuleException( message );
         }
+    }
 
+    /**
+     * The project's remote repositories to use for the resolution of either plugins or dependencies.
+     * Standard implementation returns the remote repositories for dependencies.
+     * 
+     * @throws EnforcerRuleException 
+     */
+    protected List<RemoteRepository> getRemoteRepositories( EnforcerRuleHelper helper ) throws EnforcerRuleException
+    {
+        try
+        {
+            return (List<RemoteRepository>) Objects.requireNonNull( helper.evaluate( "${project.remoteProjectRepositories}" ),
+                    "${project.remoteProjectRepositories} is null");
+        }
+        catch ( ExpressionEvaluationException eee )
+        {
+            throw new EnforcerRuleException( "Unable to retrieve project's remote repositories", eee );
+        }
     }
 
     protected CharSequence getErrorMessage( Artifact artifact )
@@ -120,43 +122,36 @@ public abstract class AbstractBanDependencies
         return "Found Banned Dependency: " + artifact.getId() + System.lineSeparator();
     }
 
-    private Set<Artifact> getDependenciesToCheck( EnforcerRuleHelper helper,
-            ProjectBuildingRequest buildingRequest )
+    private Map<Artifact, DependencyNode> getDependenciesToCheck( EnforcerRuleHelper helper,
+            MavenProject project )
     {
-        String cacheKey = buildingRequest.getProject().getId() + "_" + searchTransitive;
+        String cacheKey = project.getId() + "_" + searchTransitive;
 
         // check in the cache
-        Set<Artifact> dependencies =
-                (Set<Artifact>) helper.getCache( cacheKey, () -> getDependenciesToCheck( buildingRequest ) );
+        Map<Artifact, DependencyNode> dependencies =
+                (Map<Artifact, DependencyNode>) helper.getCache( cacheKey, () -> {
+                    // TODO: first check deprecated method
+                    try {
+                        return resolverHelper.getDependencies( project, searchTransitive );
+                    } catch (DependencyCollectionException e) {
+                        throw new RuntimeException( e );
+                    }
+                    
+                } );
 
         return dependencies;
     }
 
-    protected Set<Artifact> getDependenciesToCheck( ProjectBuildingRequest buildingRequest )
+    /**
+     * Rather use
+     * @param project
+     * @return
+     * @deprecated Use {@link #getDependencyMapToCheck(MavenProject)} instead
+     */
+    @Deprecated
+    protected Set<Artifact> getDependenciesToCheck( ProjectBuildingRequest request )
     {
-        Set<Artifact> dependencies = null;
-        try
-        {
-            DependencyNode node = graphBuilder.buildDependencyGraph( buildingRequest, null );
-            if ( searchTransitive )
-            {
-                dependencies = ArtifactUtils.getAllDescendants( node );
-            }
-            else if ( node.getChildren() != null )
-            {
-                dependencies = new HashSet<>();
-                for ( DependencyNode depNode : node.getChildren() )
-                {
-                    dependencies.add( depNode.getArtifact() );
-                }
-            }
-        }
-        catch ( DependencyGraphBuilderException e )
-        {
-            // otherwise we need to change the signature of this protected method
-            throw new RuntimeException( e );
-        }
-        return dependencies;
+        return null;
     }
 
     /**
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java
index e7ef71b..c42617a 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java
@@ -28,14 +28,13 @@ import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher;
+import org.apache.maven.plugins.enforcer.utils.ResolverHelper;
 import org.apache.maven.project.DefaultProjectBuildingRequest;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyGraphBuilder;
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 import org.codehaus.plexus.logging.console.ConsoleLogger;
+import org.eclipse.aether.graph.DependencyNode;
 
 /**
  * This rule bans all transitive dependencies. There is a configuration option to exclude certain artifacts from being
@@ -161,13 +160,9 @@ public class BanTransitiveDependencies
         try
         {
             MavenProject project = (MavenProject) helper.evaluate( "${project}" );
-            MavenSession session = (MavenSession) helper.evaluate( "${session}" );
-            
-            ProjectBuildingRequest buildingRequest =
-                new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
-            buildingRequest.setProject( project );
-            
-            rootNode = createDependencyGraphBuilder().buildDependencyGraph( buildingRequest, null );
+
+            ResolverHelper resolverHelper = new ResolverHelper( helper );
+            rootNode = resolverHelper.collectDependencies( project );
         }
         catch ( Exception e )
         {
@@ -195,18 +190,4 @@ public class BanTransitiveDependencies
 
     }
 
-    private DependencyGraphBuilder createDependencyGraphBuilder()
-        throws ComponentLookupException
-    {
-        // CHECKSTYLE_OFF: LineLength
-        DefaultDependencyGraphBuilder builder =
-            (DefaultDependencyGraphBuilder) helper.getContainer().lookup( DependencyGraphBuilder.class.getCanonicalName(),
-                                                                          "default" );
-        // CHECKSTYLE_ON: LineLength
-
-        builder.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DISABLED, "DefaultDependencyGraphBuilder" ) );
-
-        return builder;
-    }
-
 }
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BannedPlugins.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BannedPlugins.java
index 9e0a7e8..74d2def 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BannedPlugins.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BannedPlugins.java
@@ -33,9 +33,9 @@ public class BannedPlugins
     extends BannedDependencies
 {
     @Override
-    protected Set<Artifact> getDependenciesToCheck( ProjectBuildingRequest buildingRequest )
+    protected Set<Artifact> getDependenciesToCheck( ProjectBuildingRequest request )
     {
-        return buildingRequest.getProject().getPluginArtifacts();
+        return request.getProject().getPluginArtifacts();
     }
 
     @Override
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/DependencyConvergence.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/DependencyConvergence.java
index fdb95e0..eb917b6 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/DependencyConvergence.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/DependencyConvergence.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.enforcer.rule.api.EnforcerRule;
@@ -32,14 +33,13 @@ import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.plugins.enforcer.utils.DependencyVersionMap;
-import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.plugins.enforcer.utils.ResolverHelper;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
 
 /**
  * @author <a href="mailto:rex@e-hoffman.org">Rex Hoffman</a>
@@ -74,26 +74,18 @@ public class DependencyConvergence
         try
         {
             MavenProject project = (MavenProject) helper.evaluate( "${project}" );
-            MavenSession session = (MavenSession) helper.evaluate( "${session}" );
-            DependencyCollectorBuilder dependencyCollectorBuilder =
-                helper.getComponent( DependencyCollectorBuilder.class );
-            ArtifactRepository repository = (ArtifactRepository) helper.evaluate( "${localRepository}" );
-
-            ProjectBuildingRequest buildingRequest =
-                new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
-            buildingRequest.setProject( project );
-            buildingRequest.setLocalRepository( repository );
+            ResolverHelper resolverHelper = new ResolverHelper( helper );
             ArtifactFilter filter = ( Artifact a ) -> ( "compile".equalsIgnoreCase( a.getScope () )
                     || "runtime".equalsIgnoreCase( a.getScope () ) )
                     && !a.isOptional();
 
-            return dependencyCollectorBuilder.collectDependencyGraph( buildingRequest, filter );
+            return resolverHelper.collectDependencies( project );
         }
-        catch ( ExpressionEvaluationException | ComponentLookupException e )
+        catch ( ExpressionEvaluationException e )
         {
             throw new EnforcerRuleException( "Unable to lookup a component " + e.getLocalizedMessage(), e );
         }
-        catch ( DependencyCollectorBuilderException e )
+        catch ( DependencyCollectionException e )
         {
             throw new EnforcerRuleException( "Could not build dependency tree " + e.getLocalizedMessage(), e );
         }
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactUtils.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactUtils.java
index b9a04af..234ee3f 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactUtils.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactUtils.java
@@ -1,5 +1,7 @@
 package org.apache.maven.plugins.enforcer.utils;
 
+import java.util.Collection;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -22,13 +24,18 @@ package org.apache.maven.plugins.enforcer.utils;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
+import org.apache.maven.model.Dependency;
 import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher.Pattern;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.graph.DependencyNode;
 
 /**
  * 
@@ -126,4 +133,9 @@ public final class ArtifactUtils
         return result;
     }
 
+    public static List<org.eclipse.aether.graph.Dependency> toDependencies( List<Dependency> dependencies,
+            ArtifactTypeRegistry types )
+    {
+        return dependencies.stream().map( d-> RepositoryUtils.toDependency( d, types )).collect( Collectors.toList() );
+    }
 }
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ConflictingDependencyVersionCollector.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ConflictingDependencyVersionCollector.java
new file mode 100644
index 0000000..e7376ee
--- /dev/null
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ConflictingDependencyVersionCollector.java
@@ -0,0 +1,49 @@
+package org.apache.maven.plugins.enforcer.utils;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.graph.DependencyVisitor;
+
+public class ConflictingDependencyVersionCollector implements DependencyVisitor {
+
+    private final Map<Key, List<DependencyNode>> keysToNodes;
+
+    ConflictingDependencyVersionCollector() {
+        keysToNodes = new HashMap<>();
+    }
+    private static final class Key
+    {
+        private final String artifactId;
+        private final String groupId;
+
+        public Key(Artifact artifact) {
+            this(artifact.getArtifactId(), artifact.getGroupId());
+        }
+        public Key(String artifactId, String groupId) {
+            super();
+            this.artifactId = artifactId;
+            this.groupId = groupId;
+        }
+    }
+    
+    @Override
+    public boolean visitEnter( DependencyNode node )
+    {
+        Key key = new Key(node.getArtifact());
+        keysToNodes.merge(key, new LinkedList<DependencyNode>(node), nodes -> nodes.add( node ));
+        return false;
+    }
+
+    @Override
+    public boolean visitLeave( DependencyNode node )
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/DependencyVersionMap.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/DependencyVersionMap.java
index fa65546..8938386 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/DependencyVersionMap.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/DependencyVersionMap.java
@@ -33,6 +33,7 @@ import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
  * @author Brian Fox
  *
  */
+@Deprecated
 public class DependencyVersionMap
     implements DependencyNodeVisitor
 {
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ResolverHelper.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ResolverHelper.java
new file mode 100644
index 0000000..3281035
--- /dev/null
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ResolverHelper.java
@@ -0,0 +1,117 @@
+package org.apache.maven.plugins.enforcer.utils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.CollectResult;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
+
+public class ResolverHelper {
+    
+    private final RepositorySystem repoSystem;
+    private final RepositorySystemSession repoSession;
+    private final List<RemoteRepository> remoteRepositories;
+    private final List<RemoteRepository> remotePluginRepositories;
+    
+    public ResolverHelper( EnforcerRuleHelper helper ) throws EnforcerRuleException
+    {
+        try
+        {
+            repoSession =
+                (RepositorySystemSession) Objects.requireNonNull( helper.evaluate( "${repositorySystemSession}" ),
+                                                                  "${repositorySystemSession} is null" );
+        }
+        catch ( ExpressionEvaluationException eee )
+        {
+            throw new EnforcerRuleException( "Unable to retrieve repositorySystemSession", eee );
+        }
+        remoteRepositories = getRemoteRepositories( helper );
+        remotePluginRepositories = getRemotePluginRepositories( helper );
+        try 
+        {
+            repoSystem = helper.getComponent( RepositorySystem.class );
+        }
+        catch ( ComponentLookupException cle )
+        {
+            throw new EnforcerRuleException( "Unable to lookup component RepositorySystem", cle );
+        }
+    }
+
+    /**
+     * The project's remote repositories to use for the resolution of dependencies.
+     * 
+     * @throws EnforcerRuleException 
+     */
+    private List<RemoteRepository> getRemoteRepositories( EnforcerRuleHelper helper ) throws EnforcerRuleException
+    {
+        try
+        {
+            return (List<RemoteRepository>) Objects.requireNonNull( helper.evaluate( "${project.remoteProjectRepositories}" ),
+                    "${project.remoteProjectRepositories} is null");
+        }
+        catch ( ExpressionEvaluationException eee )
+        {
+            throw new EnforcerRuleException( "Unable to retrieve project's remote repositories", eee );
+        }
+    }
+
+    /**
+     * The project's remote repositories to use for the resolution of plugins.
+     * @throws EnforcerRuleException 
+     */
+    private List<RemoteRepository> getRemotePluginRepositories( EnforcerRuleHelper helper ) throws EnforcerRuleException
+    {
+        try
+        {
+            return (List<RemoteRepository>) Objects.requireNonNull( helper.evaluate( "${project.remotePluginRepositories}" ),
+                    "${project.remotePluginRepositories} is null");
+        }
+        catch ( ExpressionEvaluationException eee )
+        {
+            throw new EnforcerRuleException( "Unable to retrieve project's remote plugin repositories", eee );
+        }
+    }
+
+    public Map<Artifact, DependencyNode> getDependencies( MavenProject project, boolean searchTransitive ) throws DependencyCollectionException
+    {
+        Map<Artifact, DependencyNode> dependencies = null;
+        DependencyNode node = collectDependencies(project);
+        if ( searchTransitive )
+        {
+            // TODO:!
+            dependencies = null; // ArtifactUtils.getAllDescendants( node );
+        }
+        else if ( node.getChildren() != null )
+        {
+            dependencies = new HashMap<>();
+            for ( DependencyNode depNode : node.getChildren() )
+            {
+                dependencies.putIfAbsent( RepositoryUtils.toArtifact( depNode.getArtifact() ), depNode );
+            }
+        }
+        return dependencies;
+    }
+
+    public DependencyNode collectDependencies(MavenProject project) throws DependencyCollectionException {
+        List<org.eclipse.aether.graph.Dependency> resolverDeps = ArtifactUtils.toDependencies( project.getDependencies(), repoSession.getArtifactTypeRegistry() );
+        List<org.eclipse.aether.graph.Dependency> resolvedManagedDeps = ArtifactUtils.toDependencies( project.getDependencyManagement().getDependencies(), repoSession.getArtifactTypeRegistry() );
+        CollectRequest collectRequest = new CollectRequest( resolverDeps, resolvedManagedDeps, remoteRepositories );
+        CollectResult collectResult = repoSystem.collectDependencies( repoSession, collectRequest );
+        DependencyNode node = collectResult.getRoot();
+        return node;
+    }
+}
diff --git a/pom.xml b/pom.xml
index 4f06e61..b5f6c9e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -169,11 +169,6 @@
           </exclusion>
         </exclusions>
       </dependency>
-      <dependency>
-        <groupId>org.apache.maven.shared</groupId>
-        <artifactId>maven-dependency-tree</artifactId>
-        <version>3.1.1</version>
-      </dependency>
       <dependency>
         <groupId>org.apache.maven.shared</groupId>
         <artifactId>maven-shared-utils</artifactId>