You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2023/03/11 20:04:11 UTC
[maven-enforcer] 01/01: [MENFORCER-469] Fix banTransitiveDependencies and transitive dependencies with another version than the resolved one
This is an automated email from the ASF dual-hosted git repository.
sjaranowski pushed a commit to branch MENFORCER-469
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git
commit 8ddf0c00e6ed3e0f20cad22ef60d4d87ff74a4fc
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Sat Mar 11 20:54:02 2023 +0100
[MENFORCER-469] Fix banTransitiveDependencies and transitive dependencies with another version than the resolved one
- rename ResolveUtil to ResolverUtil
- introduce methods:
- resolveTransitiveDependenciesVerbose
resolve with full tree contains all dependencies - also conflicted
- resolveTransitiveDependencies
resolve final tree contains dependencies after conflict resolved
---
.../dependency/BanTransitiveDependencies.java | 8 +--
.../rules/dependency/BannedDependencies.java | 4 +-
.../rules/dependency/BannedDependenciesBase.java | 8 +--
.../rules/dependency/DependencyConvergence.java | 8 +--
.../rules/dependency/RequireReleaseDeps.java | 4 +-
.../rules/dependency/RequireUpperBoundDeps.java | 8 +--
.../{ResolveUtil.java => ResolverUtil.java} | 53 ++++++++++------
.../rules/dependency/BannedDependenciesTest.java | 6 +-
.../rules/dependency/RequireReleaseDepsTest.java | 23 +++----
.../dependency/RequireUpperBoundDepsTest.java | 4 +-
.../pom.xml | 70 ++++++++++++++++++++++
.../pom.xml | 69 +++++++++++++++++++++
12 files changed, 213 insertions(+), 52 deletions(-)
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BanTransitiveDependencies.java
index 212d3e4..4bf2b6e 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BanTransitiveDependencies.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BanTransitiveDependencies.java
@@ -68,12 +68,12 @@ public final class BanTransitiveDependencies extends AbstractStandardEnforcerRul
private final MavenSession session;
- private final ResolveUtil resolveUtil;
+ private final ResolverUtil resolverUtil;
@Inject
- public BanTransitiveDependencies(MavenSession session, ResolveUtil resolveUtil) {
+ public BanTransitiveDependencies(MavenSession session, ResolverUtil resolverUtil) {
this.session = Objects.requireNonNull(session);
- this.resolveUtil = Objects.requireNonNull(resolveUtil);
+ this.resolverUtil = Objects.requireNonNull(resolverUtil);
}
/**
@@ -147,7 +147,7 @@ public final class BanTransitiveDependencies extends AbstractStandardEnforcerRul
.map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry))
.collect(Collectors.toSet());
- DependencyNode rootNode = resolveUtil.resolveTransitiveDependencies();
+ DependencyNode rootNode = resolverUtil.resolveTransitiveDependencies();
StringBuilder generatedMessage = new StringBuilder();
if (searchTree(rootNode, 0, exclusions, directDependencies, generatedMessage)) {
throw new EnforcerRuleException(ofNullable(getMessage()).orElse(generatedMessage.toString()));
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependencies.java
index 77d2e17..3a03f5e 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependencies.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependencies.java
@@ -34,8 +34,8 @@ import org.apache.maven.execution.MavenSession;
public final class BannedDependencies extends BannedDependenciesBase {
@Inject
- BannedDependencies(MavenSession session, ResolveUtil resolveUtil) {
- super(session, resolveUtil);
+ BannedDependencies(MavenSession session, ResolverUtil resolverUtil) {
+ super(session, resolverUtil);
}
@Override
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
index 4ee240e..ad6cd1c 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesBase.java
@@ -67,11 +67,11 @@ abstract class BannedDependenciesBase extends AbstractStandardEnforcerRule {
private final MavenSession session;
- private final ResolveUtil resolveUtil;
+ private final ResolverUtil resolverUtil;
- BannedDependenciesBase(MavenSession session, ResolveUtil resolveUtil) {
+ BannedDependenciesBase(MavenSession session, ResolverUtil resolverUtil) {
this.session = Objects.requireNonNull(session);
- this.resolveUtil = Objects.requireNonNull(resolveUtil);
+ this.resolverUtil = Objects.requireNonNull(resolverUtil);
}
protected MavenSession getSession() {
@@ -102,7 +102,7 @@ abstract class BannedDependenciesBase extends AbstractStandardEnforcerRule {
}
} else {
StringBuilder messageBuilder = new StringBuilder();
- DependencyNode rootNode = resolveUtil.resolveTransitiveDependencies();
+ DependencyNode rootNode = resolverUtil.resolveTransitiveDependenciesVerbose();
if (!validate(rootNode, 0, messageBuilder)) {
String message = "";
if (getMessage() != null) {
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/DependencyConvergence.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/DependencyConvergence.java
index eb583c7..b742cd2 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/DependencyConvergence.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/DependencyConvergence.java
@@ -52,17 +52,17 @@ public final class DependencyConvergence extends AbstractStandardEnforcerRule {
private DependencyVersionMap dependencyVersionMap;
- private final ResolveUtil resolveUtil;
+ private final ResolverUtil resolverUtil;
@Inject
- public DependencyConvergence(ResolveUtil resolveUtil) {
- this.resolveUtil = Objects.requireNonNull(resolveUtil);
+ public DependencyConvergence(ResolverUtil resolverUtil) {
+ this.resolverUtil = Objects.requireNonNull(resolverUtil);
}
@Override
public void execute() throws EnforcerRuleException {
- DependencyNode node = resolveUtil.resolveTransitiveDependencies(
+ DependencyNode node = resolverUtil.resolveTransitiveDependenciesVerbose(
// TODO: use a modified version of ExclusionDependencySelector to process excludes and includes
new DependencySelector() {
@Override
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDeps.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDeps.java
index 246ae7c..48d4e33 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDeps.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDeps.java
@@ -51,8 +51,8 @@ public final class RequireReleaseDeps extends BannedDependenciesBase {
private boolean failWhenParentIsSnapshot = true;
@Inject
- public RequireReleaseDeps(MavenSession session, ResolveUtil resolveUtil) {
- super(session, resolveUtil);
+ public RequireReleaseDeps(MavenSession session, ResolverUtil resolverUtil) {
+ super(session, resolverUtil);
}
// Override parent to allow optional ignore of this rule.
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDeps.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDeps.java
index 27f7889..9157bd9 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDeps.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDeps.java
@@ -71,11 +71,11 @@ public final class RequireUpperBoundDeps extends AbstractStandardEnforcerRule {
private RequireUpperBoundDepsVisitor upperBoundDepsVisitor;
- private final ResolveUtil resolveUtil;
+ private final ResolverUtil resolverUtil;
@Inject
- public RequireUpperBoundDeps(ResolveUtil resolveUtil) {
- this.resolveUtil = Objects.requireNonNull(resolveUtil);
+ public RequireUpperBoundDeps(ResolverUtil resolverUtil) {
+ this.resolverUtil = Objects.requireNonNull(resolverUtil);
}
/**
@@ -97,7 +97,7 @@ public final class RequireUpperBoundDeps extends AbstractStandardEnforcerRule {
@Override
public void execute() throws EnforcerRuleException {
- DependencyNode node = resolveUtil.resolveTransitiveDependencies();
+ DependencyNode node = resolverUtil.resolveTransitiveDependenciesVerbose();
upperBoundDepsVisitor = new RequireUpperBoundDepsVisitor()
.setUniqueVersions(uniqueVersions)
.setIncludes(includes);
diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolveUtil.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolverUtil.java
similarity index 73%
rename from enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolveUtil.java
rename to enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolverUtil.java
index 1337fed..fa95587 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolveUtil.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/dependency/ResolverUtil.java
@@ -39,33 +39,47 @@ import org.eclipse.aether.collection.DependencySelector;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
import org.eclipse.aether.util.graph.selector.AndDependencySelector;
-import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
-import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
-import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
import org.eclipse.aether.util.graph.transformer.ConflictResolver;
import static java.util.Optional.ofNullable;
-import static org.apache.maven.artifact.Artifact.SCOPE_PROVIDED;
-import static org.apache.maven.artifact.Artifact.SCOPE_TEST;
/**
* Resolver helper class.
*/
@Named
-class ResolveUtil {
+class ResolverUtil {
private final RepositorySystem repositorySystem;
+
private final MavenSession session;
/**
* Default constructor
*/
@Inject
- ResolveUtil(RepositorySystem repositorySystem, MavenSession session) {
+ ResolverUtil(RepositorySystem repositorySystem, MavenSession session) {
this.repositorySystem = Objects.requireNonNull(repositorySystem);
this.session = Objects.requireNonNull(session);
}
+ /**
+ * Retrieves the {@link DependencyNode} instance containing the result of the transitive dependency
+ * for the current {@link MavenProject} in verbose mode.
+ * <p>
+ * In verbose mode all nodes participating in a conflict are retained.
+ * </p>
+ * <p>
+ * Please consult {@link ConflictResolver} and {@link DependencyManagerUtils}>
+ * /p>
+ *
+ * @param selectors zero or more {@link DependencySelector} instances
+ * @return a Dependency Node which is the root of the project's dependency tree
+ * @throws EnforcerRuleException thrown if the lookup fails
+ */
+ DependencyNode resolveTransitiveDependenciesVerbose(DependencySelector... selectors) throws EnforcerRuleException {
+ return resolveTransitiveDependencies(true, selectors);
+ }
+
/**
* Retrieves the {@link DependencyNode} instance containing the result of the transitive dependency
* for the current {@link MavenProject}.
@@ -75,13 +89,12 @@ class ResolveUtil {
* @throws EnforcerRuleException thrown if the lookup fails
*/
DependencyNode resolveTransitiveDependencies(DependencySelector... selectors) throws EnforcerRuleException {
- if (selectors.length == 0) {
- selectors = new DependencySelector[] {
- new ScopeDependencySelector(SCOPE_TEST, SCOPE_PROVIDED),
- new OptionalDependencySelector(),
- new ExclusionDependencySelector()
- };
- }
+ return resolveTransitiveDependencies(false, selectors);
+ }
+
+ private DependencyNode resolveTransitiveDependencies(boolean verbose, DependencySelector... selectors)
+ throws EnforcerRuleException {
+
try {
MavenProject project = session.getCurrentProject();
ArtifactTypeRegistry artifactTypeRegistry =
@@ -89,9 +102,15 @@ class ResolveUtil {
DefaultRepositorySystemSession repositorySystemSession =
new DefaultRepositorySystemSession(session.getRepositorySession());
- repositorySystemSession.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
- repositorySystemSession.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
- repositorySystemSession.setDependencySelector(new AndDependencySelector(selectors));
+
+ if (selectors.length > 0) {
+ repositorySystemSession.setDependencySelector(new AndDependencySelector(selectors));
+ }
+
+ if (verbose) {
+ repositorySystemSession.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
+ repositorySystemSession.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+ }
CollectRequest collectRequest = new CollectRequest(
project.getDependencies().stream()
diff --git a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesTest.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesTest.java
index 69ad445..c01748c 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesTest.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/BannedDependenciesTest.java
@@ -51,7 +51,7 @@ class BannedDependenciesTest {
private MavenSession session;
@Mock
- private ResolveUtil resolveUtil;
+ private ResolverUtil resolverUtil;
@InjectMocks
private BannedDependencies rule;
@@ -94,7 +94,7 @@ class BannedDependenciesTest {
@Test
void excludesUseTransitiveDependencies() throws Exception {
- when(resolveUtil.resolveTransitiveDependencies())
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
.thenReturn(new DependencyNodeBuilder()
.withType(DependencyNodeBuilder.Type.POM)
.withChildNode(new DependencyNodeBuilder()
@@ -127,7 +127,7 @@ class BannedDependenciesTest {
@Test
void excludesAndIncludesUseTransitiveDependencies() throws Exception {
- when(resolveUtil.resolveTransitiveDependencies())
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
.thenReturn(new DependencyNodeBuilder()
.withType(DependencyNodeBuilder.Type.POM)
.withChildNode(new DependencyNodeBuilder()
diff --git a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDepsTest.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDepsTest.java
index b1409a6..676479d 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDepsTest.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireReleaseDepsTest.java
@@ -56,7 +56,7 @@ class RequireReleaseDepsTest {
private MavenSession session;
@Mock
- private ResolveUtil resolveUtil;
+ private ResolverUtil resolverUtil;
@InjectMocks
private RequireReleaseDeps rule;
@@ -75,12 +75,12 @@ class RequireReleaseDepsTest {
assertThatCode(rule::execute).doesNotThrowAnyException();
- verifyNoInteractions(resolveUtil);
+ verifyNoInteractions(resolverUtil);
}
@Test
void testSearchTransitiveMultipleFailures() throws Exception {
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(getDependencyNodeWithMultipleSnapshots());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose()).thenReturn(getDependencyNodeWithMultipleSnapshots());
rule.setSearchTransitive(true);
assertThatCode(rule::execute)
@@ -94,7 +94,7 @@ class RequireReleaseDepsTest {
@Test
void testSearchTransitiveNoFailures() throws Exception {
when(session.getCurrentProject()).thenReturn(project);
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(new DependencyNodeBuilder().build());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose()).thenReturn(new DependencyNodeBuilder().build());
rule.setSearchTransitive(true);
assertThatCode(rule::execute).doesNotThrowAnyException();
@@ -108,13 +108,14 @@ class RequireReleaseDepsTest {
assertThatCode(rule::execute).doesNotThrowAnyException();
- verifyNoInteractions(resolveUtil);
+ verifyNoInteractions(resolverUtil);
}
@Test
void testWildcardExcludeTests() throws Exception {
when(session.getCurrentProject()).thenReturn(project);
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(getDependencyNodeWithMultipleTestSnapshots());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
+ .thenReturn(getDependencyNodeWithMultipleTestSnapshots());
rule.setExcludes(Collections.singletonList("*:*:*:*:test"));
rule.setSearchTransitive(true);
@@ -125,7 +126,8 @@ class RequireReleaseDepsTest {
@Test
void testWildcardExcludeAll() throws Exception {
when(session.getCurrentProject()).thenReturn(project);
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(getDependencyNodeWithMultipleTestSnapshots());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
+ .thenReturn(getDependencyNodeWithMultipleTestSnapshots());
rule.setExcludes(Collections.singletonList("*"));
rule.setSearchTransitive(true);
@@ -135,7 +137,8 @@ class RequireReleaseDepsTest {
@Test
void testExcludesAndIncludes() throws Exception {
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(getDependencyNodeWithMultipleTestSnapshots());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
+ .thenReturn(getDependencyNodeWithMultipleTestSnapshots());
rule.setExcludes(Collections.singletonList("*"));
rule.setIncludes(Collections.singletonList("*:*:*:*:test"));
@@ -161,7 +164,7 @@ class RequireReleaseDepsTest {
void testFailWhenParentIsSnapshot() throws Exception {
when(session.getCurrentProject()).thenReturn(project);
when(project.getParentArtifact()).thenReturn(ARTIFACT_STUB_FACTORY.getSnapshotArtifact());
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(new DependencyNodeBuilder().build());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose()).thenReturn(new DependencyNodeBuilder().build());
rule.setFailWhenParentIsSnapshot(true);
@@ -174,7 +177,7 @@ class RequireReleaseDepsTest {
void parentShouldBeExcluded() throws Exception {
when(session.getCurrentProject()).thenReturn(project);
when(project.getParentArtifact()).thenReturn(ARTIFACT_STUB_FACTORY.getSnapshotArtifact());
- when(resolveUtil.resolveTransitiveDependencies()).thenReturn(new DependencyNodeBuilder().build());
+ when(resolverUtil.resolveTransitiveDependenciesVerbose()).thenReturn(new DependencyNodeBuilder().build());
rule.setFailWhenParentIsSnapshot(true);
rule.setExcludes(Collections.singletonList("testGroupId:*"));
diff --git a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDepsTest.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDepsTest.java
index 5cbbe30..8741e97 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDepsTest.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/dependency/RequireUpperBoundDepsTest.java
@@ -33,7 +33,7 @@ import static org.mockito.Mockito.when;
class RequireUpperBoundDepsTest {
@Mock
- private ResolveUtil resolveUtil;
+ private ResolverUtil resolverUtil;
@InjectMocks
private RequireUpperBoundDeps rule;
@@ -41,7 +41,7 @@ class RequireUpperBoundDepsTest {
@Test
void testRule() throws Exception {
- when(resolveUtil.resolveTransitiveDependencies())
+ when(resolverUtil.resolveTransitiveDependenciesVerbose())
.thenReturn(new DependencyNodeBuilder()
.withType(DependencyNodeBuilder.Type.POM)
.withChildNode(new DependencyNodeBuilder()
diff --git a/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep1/pom.xml b/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep1/pom.xml
new file mode 100644
index 0000000..01a1d9b
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep1/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+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.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.enforcer</groupId>
+ <artifactId>ban-transitive-test</artifactId>
+ <version>1.0</version>
+
+ <url>https://issues.apache.org/jira/browse/MENFORCER-469</url>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>test</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <banTransitiveDependencies/>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.plugins.enforcer.its</groupId>
+ <artifactId>menforcer128_classic</artifactId>
+ <version>0.9.9</version>
+ </dependency>
+
+ <!-- menforcer128_api the same version as in menforcer128_classic -->
+
+ <dependency>
+ <groupId>org.apache.maven.plugins.enforcer.its</groupId>
+ <artifactId>menforcer128_api</artifactId>
+ <version>1.5.0</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep2/pom.xml b/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep2/pom.xml
new file mode 100644
index 0000000..ad69e5a
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/ban-transitive-dependencies-direct-dep2/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+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.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.enforcer</groupId>
+ <artifactId>ban-transitive-test</artifactId>
+ <version>1.0</version>
+
+ <url>https://issues.apache.org/jira/browse/MENFORCER-469</url>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>test</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <banTransitiveDependencies/>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.plugins.enforcer.its</groupId>
+ <artifactId>menforcer128_classic</artifactId>
+ <version>0.9.9</version>
+ </dependency>
+
+ <!-- menforcer128_api override version, in menforcer128_classic is 1.5.0 -->
+ <dependency>
+ <groupId>org.apache.maven.plugins.enforcer.its</groupId>
+ <artifactId>menforcer128_api</artifactId>
+ <version>1.6.0</version>
+ </dependency>
+ </dependencies>
+
+</project>