diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java index 90bb3c1eb..9996eb6a4 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java @@ -51,6 +51,9 @@ * or applied in same POM) are always applied. This implementation makes sure, that version and scope are not applied * onto same node that actually provided the rules, to no override work that ModelBuilder did. It achieves this goal * by tracking "depth" for each collected rule and ignoring rules coming from same depth as processed dependency node is. + *

+ * Note for future: the field {@code managedLocalPaths} is intentionally left out of hash/equals, with + * reason explained above. * * @since 2.0.0 */ @@ -113,15 +116,8 @@ protected AbstractDependencyManager( // nullable: if using scope manager, but there is no system scope defined this.systemDependencyScope = systemDependencyScope; - this.hashCode = Objects.hash( - depth, - deriveUntil, - applyFrom, - managedVersions, - managedScopes, - managedOptionals, - managedLocalPaths, - managedExclusions); + // exclude managedLocalPaths + this.hashCode = Objects.hash(depth, managedVersions, managedScopes, managedOptionals, managedExclusions); } protected abstract DependencyManager newInstance( @@ -185,7 +181,7 @@ public DependencyManager deriveChildManager(DependencyCollectionContext context) Collection exclusions = managedDependency.getExclusions(); if (!exclusions.isEmpty()) { if (managedExclusions == this.managedExclusions) { - managedExclusions = MMap.copy(this.managedExclusions); + managedExclusions = MMap.copyWithKey(key, this.managedExclusions); } Collection>> managed = managedExclusions.get(key); if (managed == null) { @@ -320,13 +316,11 @@ public boolean equals(Object obj) { } AbstractDependencyManager that = (AbstractDependencyManager) obj; + // exclude managedLocalPaths return depth == that.depth - && deriveUntil == that.deriveUntil - && applyFrom == that.applyFrom && managedVersions.equals(that.managedVersions) && managedScopes.equals(that.managedScopes) && managedOptionals.equals(that.managedOptionals) - && managedLocalPaths.equals(that.managedLocalPaths) && managedExclusions.equals(that.managedExclusions); } diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/MMap.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/MMap.java index af7aa34cf..78789b41f 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/MMap.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/MMap.java @@ -18,6 +18,8 @@ */ package org.eclipse.aether.util.graph.manager; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; /** @@ -47,6 +49,12 @@ public static MMap copy(MMap orig) { return new MMap<>(new HashMap<>(orig.delegate)); } + public static MMap> copyWithKey(K key, MMap> orig) { + HashMap> delegateLocal = new HashMap<>(orig.delegate); + delegateLocal.computeIfPresent(key, (k, v) -> new ArrayList<>(v)); + return new MMap<>(delegateLocal); + } + protected final HashMap delegate; private MMap(HashMap delegate) {