You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/08/28 12:53:51 UTC

(maven) 01/04: [MNG-7826] Validate plugin transitive dependencies as well

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

slachiewicz pushed a commit to branch rebased/pr-1188-experiment-plugin-depMgt-maven-3.9.x
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 7b30d8efd0ff03c8801e75df8efe4899c7d259c8
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Mon Jun 26 17:29:08 2023 +0200

    [MNG-7826] Validate plugin transitive dependencies as well
    
    As 3.9.3 lost this capability as it goes only for POM (direct dependencies)
    while transitive also does tell a lot.
    
    Example output with this PR:
    ```
    [WARNING]
    [WARNING] Plugin [INTERNAL, EXTERNAL] validation issues were detected in following plugin(s)
    [WARNING]
    [WARNING]  * org.jacoco:jacoco-maven-plugin:0.8.10
    [WARNING]   Plugin EXTERNAL issue(s):
    [WARNING]    * Transitive dependencies contain Maven 2.x artifacts, which will be not supported in Maven 4.x
    [WARNING]    * Transitive dependencies mixes multiple Maven versions: [2.0.6, 2.0.2]
    [WARNING]    * Transitive dependencies contain plexus-container-default, which is EOL
    [WARNING]
    [WARNING]  * org.apache.maven.plugins:maven-site-plugin:3.12.1
    [WARNING]   Declared at location(s):
    [WARNING]    * com.soebes.smpp:smpp:6.0.4-SNAPSHOT (pom.xml) @ line 580
    [WARNING]   Plugin EXTERNAL issue(s):
    [WARNING]    * Direct dependencies contain Maven 2.x compatibility layer, which will be not supported in Maven 4.x
    [WARNING]    * Transitive dependencies of Maven artifacts are not in `provided` scope. If the plugin already declares them in `provided` scope, update the maven-plugin-plugin to latest version. Artifacts found with wrong scope: [org.apache.maven:maven-plugin-api:3.2.5, org.apache.maven:maven-model:3.2.5, org.apache.maven:maven-core:3.2.5, org.apache.maven:maven-settings:3.2.5, org.apache.maven:maven-model-builder:3.2.5, org.apache.maven:maven-repository-metadata:3.2.5, org.apache.mave [...]
    [WARNING]    * Transitive dependencies contain plexus-container-default, which is EOL
    [WARNING]   Mojo EXTERNAL issue(s):
    [WARNING]    * Mojo site:attach-descriptor (org.apache.maven.plugins.site.descriptor.SiteDescriptorAttachMojo)
    [WARNING]      - Parameter 'localRepository' uses deprecated parameter expression '${localRepository}': ArtifactRepository type is deprecated and its use in Mojos should be avoided.
    [WARNING]
    [WARNING]
    [WARNING] Fix reported issues by adjusting plugin configuration or by upgrading above listed plugins. If no upgrade available, please notify plugin maintainers about reported issues.
    [WARNING] For more or less details, use 'maven.plugin.validation' property with one of the values (case insensitive): [NONE, INLINE, SUMMARY, BRIEF, VERBOSE]
    [WARNING]
    ```
    
    ---
    
    https://issues.apache.org/jira/browse/MNG-7826
---
 .../AbstractMavenPluginDependenciesValidator.java  | 55 ----------------------
 .../DefaultPluginDependenciesResolver.java         | 13 +++++
 .../internal/Maven2DependenciesValidator.java      | 28 ++++++++---
 .../Maven3CompatDependenciesValidator.java         | 32 ++++++++++---
 .../internal/MavenMixedDependenciesValidator.java  | 28 ++++++++---
 .../internal/MavenPluginDependenciesValidator.java | 17 ++++++-
 .../internal/MavenScopeDependenciesValidator.java  | 31 +++++++++---
 ...lexusContainerDefaultDependenciesValidator.java | 30 +++++++++---
 8 files changed, 145 insertions(+), 89 deletions(-)

diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java
deleted file mode 100644
index 43421ce558..0000000000
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginDependenciesValidator.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.plugin.internal;
-
-import org.apache.maven.plugin.PluginValidationManager;
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.resolution.ArtifactDescriptorResult;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Service responsible for validating plugin dependencies.
- *
- * @since 3.9.2
- */
-abstract class AbstractMavenPluginDependenciesValidator implements MavenPluginDependenciesValidator {
-
-    protected final PluginValidationManager pluginValidationManager;
-
-    protected AbstractMavenPluginDependenciesValidator(PluginValidationManager pluginValidationManager) {
-        this.pluginValidationManager = requireNonNull(pluginValidationManager);
-    }
-
-    @Override
-    public void validate(
-            RepositorySystemSession session,
-            Artifact pluginArtifact,
-            ArtifactDescriptorResult artifactDescriptorResult) {
-        if (artifactDescriptorResult.getDependencies() != null) {
-            doValidate(session, pluginArtifact, artifactDescriptorResult);
-        }
-    }
-
-    protected abstract void doValidate(
-            RepositorySystemSession session,
-            Artifact pluginArtifact,
-            ArtifactDescriptorResult artifactDescriptorResult);
-}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
index b2264fc576..a7ec63d09c 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.maven.RepositoryUtils;
@@ -59,6 +60,7 @@
 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
 
 /**
@@ -219,6 +221,17 @@ private DependencyNode resolveInternal(
                 node.accept(new GraphLogger());
             }
 
+            PreorderNodeListGenerator pnl = new PreorderNodeListGenerator();
+            node.accept(pnl);
+            List<org.eclipse.aether.graph.Dependency> dependencies = pnl.getDependencies(true);
+            dependencies.remove(node.getDependency());
+            dependencies.removeAll(node.getChildren().stream()
+                    .map((DependencyNode::getDependency))
+                    .collect(Collectors.toList()));
+            for (MavenPluginDependenciesValidator dependenciesValidator : dependenciesValidators) {
+                dependenciesValidator.validate(session, node.getArtifact(), dependencies);
+            }
+
             depRequest.setRoot(node);
             repoSystem.resolveDependencies(session, depRequest);
         } catch (DependencyCollectionException e) {
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java
index d2f8dd89ce..d9736467de 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven2DependenciesValidator.java
@@ -22,6 +22,7 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -31,26 +32,40 @@
 import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Detects Maven2 plugins.
+ * Detects Maven2 plugins in dependencies.
  *
  * @since 3.9.2
  */
 @Singleton
 @Named
-class Maven2DependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+class Maven2DependenciesValidator implements MavenPluginDependenciesValidator {
+
+    private final PluginValidationManager pluginValidationManager;
 
     @Inject
     Maven2DependenciesValidator(PluginValidationManager pluginValidationManager) {
-        super(pluginValidationManager);
+        this.pluginValidationManager = requireNonNull(pluginValidationManager);
     }
 
     @Override
-    protected void doValidate(
+    public void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult) {
-        Set<String> maven2Versions = artifactDescriptorResult.getDependencies().stream()
+        doValidate(session, pluginArtifact, artifactDescriptorResult.getDependencies(), true);
+    }
+
+    @Override
+    public void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        doValidate(session, pluginArtifact, dependencies, false);
+    }
+
+    private void doValidate(
+            RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies, boolean direct) {
+        Set<String> maven2Versions = dependencies.stream()
                 .map(Dependency::getArtifact)
                 .filter(d -> "org.apache.maven".equals(d.getGroupId()))
                 .filter(d -> !DefaultPluginValidationManager.EXPECTED_PROVIDED_SCOPE_EXCLUSIONS_GA.contains(
@@ -64,7 +79,8 @@ protected void doValidate(
                     PluginValidationManager.IssueLocality.EXTERNAL,
                     session,
                     pluginArtifact,
-                    "Plugin is a Maven 2.x plugin, which will be not supported in Maven 4.x");
+                    (direct ? "Direct" : "Transitive")
+                            + " dependencies contain Maven 2.x artifacts, which will be not supported in Maven 4.x");
         }
     }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven3CompatDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven3CompatDependenciesValidator.java
index 67812245d6..46df0deb21 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven3CompatDependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/Maven3CompatDependenciesValidator.java
@@ -22,32 +22,49 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.List;
+
 import org.apache.maven.plugin.PluginValidationManager;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 import org.eclipse.aether.util.artifact.JavaScopes;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Detects Maven3 plugins using maven-compat Maven2 compatibility layer.
+ * Detects Maven3 plugins using maven-compat Maven2 compatibility layer in dependencies.
  *
- * @since 3.9.3
+ * @since 3.9.2
  */
 @Singleton
 @Named
-class Maven3CompatDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+class Maven3CompatDependenciesValidator implements MavenPluginDependenciesValidator {
+
+    private final PluginValidationManager pluginValidationManager;
 
     @Inject
     Maven3CompatDependenciesValidator(PluginValidationManager pluginValidationManager) {
-        super(pluginValidationManager);
+        this.pluginValidationManager = requireNonNull(pluginValidationManager);
     }
 
     @Override
-    protected void doValidate(
+    public void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult) {
-        for (org.eclipse.aether.graph.Dependency dependency : artifactDescriptorResult.getDependencies()) {
+        doValidate(session, pluginArtifact, artifactDescriptorResult.getDependencies(), true);
+    }
+
+    @Override
+    public void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        doValidate(session, pluginArtifact, dependencies, false);
+    }
+
+    private void doValidate(
+            RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies, boolean direct) {
+        for (Dependency dependency : dependencies) {
             if ("org.apache.maven".equals(dependency.getArtifact().getGroupId())
                     && "maven-compat".equals(dependency.getArtifact().getArtifactId())
                     && !JavaScopes.TEST.equals(dependency.getScope())) {
@@ -55,7 +72,8 @@ protected void doValidate(
                         PluginValidationManager.IssueLocality.EXTERNAL,
                         session,
                         pluginArtifact,
-                        "Plugin depends on the deprecated Maven 2.x compatibility layer, which will be not supported in Maven 4.x");
+                        (direct ? "Direct" : "Transitive")
+                                + " dependencies contain Maven 2.x compatibility layer, which will be not supported in Maven 4.x");
             }
         }
     }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java
index 27003836d3..7ef1a018b5 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenMixedDependenciesValidator.java
@@ -22,6 +22,7 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -31,26 +32,40 @@
 import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Detects mixed Maven versions in plugins.
+ * Detects mixed Maven versions in plugin dependencies.
  *
  * @since 3.9.2
  */
 @Singleton
 @Named
-class MavenMixedDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+class MavenMixedDependenciesValidator implements MavenPluginDependenciesValidator {
+
+    private final PluginValidationManager pluginValidationManager;
 
     @Inject
     MavenMixedDependenciesValidator(PluginValidationManager pluginValidationManager) {
-        super(pluginValidationManager);
+        this.pluginValidationManager = requireNonNull(pluginValidationManager);
     }
 
     @Override
-    protected void doValidate(
+    public void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult) {
-        Set<String> mavenVersions = artifactDescriptorResult.getDependencies().stream()
+        doValidate(session, pluginArtifact, artifactDescriptorResult.getDependencies(), true);
+    }
+
+    @Override
+    public void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        doValidate(session, pluginArtifact, dependencies, false);
+    }
+
+    private void doValidate(
+            RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies, boolean direct) {
+        Set<String> mavenVersions = dependencies.stream()
                 .map(Dependency::getArtifact)
                 .filter(d -> "org.apache.maven".equals(d.getGroupId()))
                 .filter(d -> !DefaultPluginValidationManager.EXPECTED_PROVIDED_SCOPE_EXCLUSIONS_GA.contains(
@@ -63,7 +78,8 @@ protected void doValidate(
                     PluginValidationManager.IssueLocality.EXTERNAL,
                     session,
                     pluginArtifact,
-                    "Plugin mixes multiple Maven versions: " + mavenVersions);
+                    (direct ? "Direct" : "Transitive") + " dependencies mixes multiple Maven versions: "
+                            + mavenVersions);
         }
     }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java
index 2ee237d4c0..8cf50e6acb 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginDependenciesValidator.java
@@ -18,21 +18,34 @@
  */
 package org.apache.maven.plugin.internal;
 
+import java.util.List;
+
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 
 /**
  * Service responsible for validating plugin dependencies.
  *
- * @since 3.9.3
+ * @since 3.9.2
  */
 interface MavenPluginDependenciesValidator {
     /**
-     * Checks mojo dependency issues.
+     * Checks mojo dependency issues by validating artifact descriptor (POM), hence, direct dependencies.
      */
     void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult);
+
+    /**
+     * Checks mojo dependency issues by validating transitive dependencies of plugin. The dependencies passed in here
+     * does NOT contain plugin, and it's direct dependencies.
+     *
+     * @since 3.9.3
+     */
+    default void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        // nothing
+    }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java
index 844197fc03..7d1c319c4c 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenScopeDependenciesValidator.java
@@ -22,35 +22,51 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.maven.plugin.PluginValidationManager;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 import org.eclipse.aether.util.artifact.JavaScopes;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Detects Maven3 dependencies scope.
+ * Detects Maven3 direct dependencies scope.
  *
- * @since 3.9.3
+ * @since 3.9.2
  */
 @Singleton
 @Named
-class MavenScopeDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+class MavenScopeDependenciesValidator implements MavenPluginDependenciesValidator {
+
+    private final PluginValidationManager pluginValidationManager;
 
     @Inject
     MavenScopeDependenciesValidator(PluginValidationManager pluginValidationManager) {
-        super(pluginValidationManager);
+        this.pluginValidationManager = requireNonNull(pluginValidationManager);
     }
 
     @Override
-    protected void doValidate(
+    public void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult) {
-        Set<String> mavenArtifacts = artifactDescriptorResult.getDependencies().stream()
+        doValidate(session, pluginArtifact, artifactDescriptorResult.getDependencies(), true);
+    }
+
+    @Override
+    public void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        doValidate(session, pluginArtifact, dependencies, false);
+    }
+
+    private void doValidate(
+            RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies, boolean direct) {
+        Set<String> mavenArtifacts = dependencies.stream()
                 .filter(d -> !JavaScopes.PROVIDED.equals(d.getScope()) && !JavaScopes.TEST.equals(d.getScope()))
                 .map(org.eclipse.aether.graph.Dependency::getArtifact)
                 .filter(a -> "org.apache.maven".equals(a.getGroupId()))
@@ -65,7 +81,8 @@ protected void doValidate(
                     PluginValidationManager.IssueLocality.EXTERNAL,
                     session,
                     pluginArtifact,
-                    "Plugin should declare Maven artifacts in `provided` scope. If the plugin already declares them in `provided` scope, update the maven-plugin-plugin to latest version. Artifacts found with wrong scope: "
+                    (direct ? "Direct" : "Transitive")
+                            + " dependencies of Maven artifacts are not in `provided` scope. If the plugin already declares them in `provided` scope, update the maven-plugin-plugin to latest version. Artifacts found with wrong scope: "
                             + mavenArtifacts);
         }
     }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java
index c0ea4e0323..dca7d7c551 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusContainerDefaultDependenciesValidator.java
@@ -22,30 +22,47 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import java.util.List;
+
 import org.apache.maven.plugin.PluginValidationManager;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.Dependency;
 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
 
+import static java.util.Objects.requireNonNull;
+
 /**
- * Detects Plexus Container Default in plugins.
+ * Detects Plexus Container Default in plugin dependencies.
  *
  * @since 3.9.2
  */
 @Singleton
 @Named
-class PlexusContainerDefaultDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
+class PlexusContainerDefaultDependenciesValidator implements MavenPluginDependenciesValidator {
+
+    private final PluginValidationManager pluginValidationManager;
 
     @Inject
     PlexusContainerDefaultDependenciesValidator(PluginValidationManager pluginValidationManager) {
-        super(pluginValidationManager);
+        this.pluginValidationManager = requireNonNull(pluginValidationManager);
     }
 
-    protected void doValidate(
+    public void validate(
             RepositorySystemSession session,
             Artifact pluginArtifact,
             ArtifactDescriptorResult artifactDescriptorResult) {
-        boolean pcdPresent = artifactDescriptorResult.getDependencies().stream()
+        doValidate(session, pluginArtifact, artifactDescriptorResult.getDependencies(), true);
+    }
+
+    @Override
+    public void validate(RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies) {
+        doValidate(session, pluginArtifact, dependencies, false);
+    }
+
+    private void doValidate(
+            RepositorySystemSession session, Artifact pluginArtifact, List<Dependency> dependencies, boolean direct) {
+        boolean pcdPresent = dependencies.stream()
                 .filter(d -> "org.codehaus.plexus".equals(d.getArtifact().getGroupId()))
                 .anyMatch(d -> "plexus-container-default".equals(d.getArtifact().getArtifactId()));
 
@@ -54,7 +71,8 @@ protected void doValidate(
                     PluginValidationManager.IssueLocality.EXTERNAL,
                     session,
                     pluginArtifact,
-                    "Plugin depends on plexus-container-default, which is EOL");
+                    (direct ? "Direct" : "Transitive")
+                            + " dependencies contain plexus-container-default, which is EOL");
         }
     }
 }