You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "jiteshkhatri11 (via GitHub)" <gi...@apache.org> on 2026/09/08 11:27:47 UTC
[PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
jiteshkhatri11 opened a new pull request, #2132:
URL: https://github.com/apache/maven-resolver/pull/2132
## Summary
Fix the `auto` conflict resolver configuration so that it selects the appropriate conflict resolver implementation based on the dependency graph size and available memory.
Previously, `auto` unconditionally delegated to `ClassicConflictResolver`.
The implementation now:
- Selects `PathConflictResolver` when the dependency graph fits within the estimated memory threshold.
- Falls back to `ClassicConflictResolver` for larger graphs.
- Ensures conflict IDs are available before making the selection.
- Keeps explicit `classic` and `path` configurations unchanged.
## Testing
- `mvn -pl maven-resolver-util -Dtest=ConflictResolverTest test`
- `mvn -pl maven-resolver-util -am test`
- `mvn -pl maven-resolver-util -DskipTests spotless:check`
- `git diff --check`
All tests passed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
Posted by "jiteshkhatri11 (via GitHub)" <gi...@apache.org>.
jiteshkhatri11 commented on PR #2132:
URL: https://github.com/apache/maven-resolver/pull/2132#issuecomment-5596321031
@gnodet Thanks for the detailed review. I went through the concerns, especially the relationship between #1938 and #1942.
I agree that the current implementation needs to address the previous PathConflictResolver memory/safety concerns before re-enabling automatic selection.
I'll first fix the `SORTED_CONFLICT_IDS` check and add the missing tests for auto selection, explicit resolver configurations, and threshold/fallback behavior.
I'll also review #1938 and #1942 to make sure the auto-selection logic is reintroduced together with the necessary safeguards.
Thanks again for pointing this out.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
Posted by "cstamas (via GitHub)" <gi...@apache.org>.
cstamas commented on PR #2132:
URL: https://github.com/apache/maven-resolver/pull/2132#issuecomment-5848404144
@jiteshkhatri11 @gnodet is this needed after https://github.com/apache/maven-resolver/pull/2153 merged?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on code in PR #2132:
URL: https://github.com/apache/maven-resolver/pull/2132#discussion_r3961179907
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -254,18 +255,76 @@ public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransfo
throws RepositoryException {
String cf = ConfigUtils.getString(
context.getSession(), DEFAULT_CONFLICT_RESOLVER_IMPL, CONFIG_PROP_CONFLICT_RESOLVER_IMPL);
+
ConflictResolver delegate;
- if (AUTO_CONFLICT_RESOLVER.equals(cf) || CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
+
+ if (AUTO_CONFLICT_RESOLVER.equals(cf)) {
+ delegate = selectConflictResolver(node, context);
+ } else if (CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
delegate = new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else if (PATH_CONFLICT_RESOLVER.equals(cf)) {
delegate = new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else {
throw new IllegalArgumentException("Unknown conflict resolver: " + cf + "; known are "
+ Arrays.asList(AUTO_CONFLICT_RESOLVER, PATH_CONFLICT_RESOLVER, CLASSIC_CONFLICT_RESOLVER));
}
+
return delegate.transformGraph(node, context);
}
+ /**
+ * Automatically selects the conflict resolver based on the estimated memory requirements.
+ * PathConflictResolver is used for dependency trees that fit within the memory threshold,
+ * while ClassicConflictResolver is used for larger trees.
+ */
+ private ConflictResolver selectConflictResolver(DependencyNode node, DependencyGraphTransformationContext context)
+ throws RepositoryException {
+
+ if (context.get(TransformationContextKeys.CONFLICT_IDS) == null) {
+ new ConflictIdSorter().transformGraph(node, context);
+ }
Review Comment:
š“ **Bug: wrong context key checked.** This checks `CONFLICT_IDS` (set by `ConflictMarker`) but should check `SORTED_CONFLICT_IDS` (set by `ConflictIdSorter`). The original code in PR #1938 correctly checked `SORTED_CONFLICT_IDS`.
As written, if `ConflictMarker` has already run (populating `CONFLICT_IDS`) but `ConflictIdSorter` hasn't, this guard passes and the sorter never runs. In practice both delegate resolvers (`ClassicConflictResolver` line 119-124 and `PathConflictResolver` line 141-146) independently check for `SORTED_CONFLICT_IDS` and call `ConflictIdSorter` themselves, so this doesn't cause a runtime failure ā but it makes this block dead code that never triggers when it should.
```suggestion
if (context.get(TransformationContextKeys.SORTED_CONFLICT_IDS) == null) {
new ConflictIdSorter().transformGraph(node, context);
}
```
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -119,8 +120,8 @@ public class ConflictResolver implements DependencyGraphTransformer {
/**
* The name of the conflict resolver implementation to use: "auto" (default), "path", or "classic" (same as Maven 3).
* <p>
Review Comment:
š” **Javadoc update is premature.** The class-level Javadoc (lines 46-53) still says PathConflictResolver is "Not yet recommended for production" and advises "All projects: Use ClassicConflictResolver for optimal correctness." This Javadoc update claims auto mode intelligently selects the right one, but the class-level docs discourage using PCR at all. Either the class-level docs should be updated to match, or this Javadoc should stay conservative.
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -254,18 +255,76 @@ public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransfo
throws RepositoryException {
String cf = ConfigUtils.getString(
context.getSession(), DEFAULT_CONFLICT_RESOLVER_IMPL, CONFIG_PROP_CONFLICT_RESOLVER_IMPL);
+
ConflictResolver delegate;
- if (AUTO_CONFLICT_RESOLVER.equals(cf) || CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
+
+ if (AUTO_CONFLICT_RESOLVER.equals(cf)) {
+ delegate = selectConflictResolver(node, context);
+ } else if (CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
delegate = new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else if (PATH_CONFLICT_RESOLVER.equals(cf)) {
delegate = new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else {
throw new IllegalArgumentException("Unknown conflict resolver: " + cf + "; known are "
+ Arrays.asList(AUTO_CONFLICT_RESOLVER, PATH_CONFLICT_RESOLVER, CLASSIC_CONFLICT_RESOLVER));
}
+
return delegate.transformGraph(node, context);
}
+ /**
+ * Automatically selects the conflict resolver based on the estimated memory requirements.
+ * PathConflictResolver is used for dependency trees that fit within the memory threshold,
+ * while ClassicConflictResolver is used for larger trees.
+ */
+ private ConflictResolver selectConflictResolver(DependencyNode node, DependencyGraphTransformationContext context)
+ throws RepositoryException {
+
+ if (context.get(TransformationContextKeys.CONFLICT_IDS) == null) {
+ new ConflictIdSorter().transformGraph(node, context);
+ }
+
+ Runtime rt = Runtime.getRuntime();
+ long available = rt.maxMemory() - (rt.totalMemory() - rt.freeMemory());
Review Comment:
ā ļø **Unreliable heap measurement.** `Runtime.freeMemory()` reflects the free space in the *currently allocated* heap, not total available memory. Its value fluctuates wildly depending on whether GC has recently run, allocation pressure from other threads, and JVM ergonomics.
This means the same dependency graph can get `PathConflictResolver` on one build and `ClassicConflictResolver` on the next, producing non-deterministic behavior ā a property Maven users don't expect from dependency resolution. The original PR #1938 had this same issue but was accepted as a pragmatic trade-off alongside extensive benchmarking and the PathConflictResolver memory optimizations. Without those optimizations, the risk is higher.
Consider requesting a GC before measurement (`System.gc()` ā advisory but common for memory heuristics), or using a fixed configurable threshold instead of runtime measurement.
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -254,18 +255,76 @@ public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransfo
throws RepositoryException {
String cf = ConfigUtils.getString(
context.getSession(), DEFAULT_CONFLICT_RESOLVER_IMPL, CONFIG_PROP_CONFLICT_RESOLVER_IMPL);
+
ConflictResolver delegate;
- if (AUTO_CONFLICT_RESOLVER.equals(cf) || CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
+
+ if (AUTO_CONFLICT_RESOLVER.equals(cf)) {
+ delegate = selectConflictResolver(node, context);
+ } else if (CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
delegate = new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else if (PATH_CONFLICT_RESOLVER.equals(cf)) {
delegate = new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else {
throw new IllegalArgumentException("Unknown conflict resolver: " + cf + "; known are "
+ Arrays.asList(AUTO_CONFLICT_RESOLVER, PATH_CONFLICT_RESOLVER, CLASSIC_CONFLICT_RESOLVER));
}
+
return delegate.transformGraph(node, context);
}
+ /**
+ * Automatically selects the conflict resolver based on the estimated memory requirements.
+ * PathConflictResolver is used for dependency trees that fit within the memory threshold,
+ * while ClassicConflictResolver is used for larger trees.
+ */
+ private ConflictResolver selectConflictResolver(DependencyNode node, DependencyGraphTransformationContext context)
+ throws RepositoryException {
+
+ if (context.get(TransformationContextKeys.CONFLICT_IDS) == null) {
+ new ConflictIdSorter().transformGraph(node, context);
+ }
+
+ Runtime rt = Runtime.getRuntime();
+ long available = rt.maxMemory() - (rt.totalMemory() - rt.freeMemory());
+
+ // Estimate the maximum number of Path tree nodes that would fit in 25% of available heap.
+ // Each Path object costs ~200 bytes (object header + fields + children list entry).
+ int maxPathNodes = (int) Math.min(available / (4L * 200), Integer.MAX_VALUE);
+
+ // Walk the dependency tree to count total nodes (including diamond-expanded duplicates).
+ // The Path tree mirrors this structure, so the count directly reflects Path tree size.
+ // Use early-exit: stop counting once we exceed the threshold.
+ if (treeExceedsThreshold(node, maxPathNodes)) {
+ return new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
+ } else {
+ return new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
+ }
+ }
Review Comment:
ā ļø **Missing tests.** The original PR #1938 that introduced this logic included 5 test cases covering: auto mode selection, explicit path/classic config dispatch, unknown config rejection, and default config behavior. This PR re-introduces the production code without any tests.
Given this code was removed for stability reasons, re-introducing it without tests ā especially for the memory threshold heuristic and the fallback behavior ā is risky. At minimum, tests should verify:
1. `auto` selects `PathConflictResolver` for small graphs
2. `auto` selects `ClassicConflictResolver` for large graphs
3. Explicit `path` and `classic` configs are unaffected
4. The tree-walking threshold check terminates early
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
Posted by "gnodet-bot (via GitHub)" <gi...@apache.org>.
gnodet-bot commented on code in PR #2132:
URL: https://github.com/apache/maven-resolver/pull/2132#discussion_r4114456788
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -254,18 +255,76 @@ public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransfo
throws RepositoryException {
String cf = ConfigUtils.getString(
context.getSession(), DEFAULT_CONFLICT_RESOLVER_IMPL, CONFIG_PROP_CONFLICT_RESOLVER_IMPL);
+
ConflictResolver delegate;
- if (AUTO_CONFLICT_RESOLVER.equals(cf) || CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
+
+ if (AUTO_CONFLICT_RESOLVER.equals(cf)) {
+ delegate = selectConflictResolver(node, context);
+ } else if (CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
delegate = new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else if (PATH_CONFLICT_RESOLVER.equals(cf)) {
delegate = new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else {
throw new IllegalArgumentException("Unknown conflict resolver: " + cf + "; known are "
+ Arrays.asList(AUTO_CONFLICT_RESOLVER, PATH_CONFLICT_RESOLVER, CLASSIC_CONFLICT_RESOLVER));
}
+
return delegate.transformGraph(node, context);
}
+ /**
+ * Automatically selects the conflict resolver based on the estimated memory requirements.
+ * PathConflictResolver is used for dependency trees that fit within the memory threshold,
+ * while ClassicConflictResolver is used for larger trees.
+ */
+ private ConflictResolver selectConflictResolver(DependencyNode node, DependencyGraphTransformationContext context)
+ throws RepositoryException {
+
+ if (context.get(TransformationContextKeys.SORTED_CONFLICT_IDS) == null) {
+ new ConflictIdSorter().transformGraph(node, context);
+ }
+
+ Runtime rt = Runtime.getRuntime();
+ long available = rt.maxMemory() - (rt.totalMemory() - rt.freeMemory());
+
+ // Estimate the maximum number of Path tree nodes that would fit in 25% of available heap.
+ // Each Path object costs ~200 bytes (object header + fields + children list entry).
+ int maxPathNodes = (int) Math.min(available / (4L * 200), Integer.MAX_VALUE);
Review Comment:
ā ļø **Still non-deterministic (not addressed from previous review).** `Runtime.freeMemory()` reflects GC state, allocation pressure from other threads, and JVM ergonomics. The same dependency graph can get `PathConflictResolver` on one invocation and `ClassicConflictResolver` on the next.
Moreover, since PR #2153 merged, `PathConflictResolver` itself uses depth-bounded expansion (`IdentityHashMap<DependencyNode, Integer>`) to cap `Path` creation. The OOM that motivated this heuristic is fixed at the source. This entire memory-estimation block is now solving a problem that no longer exists.
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -119,8 +120,8 @@ public class ConflictResolver implements DependencyGraphTransformer {
/**
* The name of the conflict resolver implementation to use: "auto" (default), "path", or "classic" (same as Maven 3).
* <p>
- * When set to "auto", the resolver will currently just use "classic". The idea here, is that this value will
- * always select the best (most robust, most performant) one, which currently is "classic".
+ * When set to "auto", the resolver automatically selects the most appropriate implementation based on the
+ * dependency graph size and available memory.
Review Comment:
š” **Javadoc contradiction not addressed (from previous review).** This property-level doc claims auto mode "automatically selects the most appropriate implementation," but the class-level Javadoc at lines 47 and 52-53 still says:
- "PathConflictResolver ā Not yet recommended for production"
- "All projects: Use ClassicConflictResolver for optimal correctness"
These are contradictory. If auto mode can select PathConflictResolver, the class-level docs need updating too ā or this Javadoc should stay conservative until the class docs are revised.
##########
maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/transformer/ConflictResolverTest.java:
##########
@@ -905,29 +929,24 @@ private static DependencyNode makeDependencyNode(
@ParameterizedTest
@MethodSource("conflictResolverSource")
void denseGraphDoesNotOom(ConflictResolver conflictResolver) throws RepositoryException {
- // M=N=K=100: without the fix, creates M*N + M*N*K = 1,010,000 Path objects (~80 MB)
- // ā OutOfMemoryError on CI. With the fix: O(N+K) = 200 expansions, trivial memory.
- int M = 100; // parent modules
- int N = 100; // hub modules (shared, each with children)
- int K = 100; // sub-hub leaf modules (shared across hubs)
+ int M = 100;
Review Comment:
ā ļø **Don't strip documentation comments from existing tests.** These comments (added by PR #2153) explain the test structure ā e.g., `M=N=K=100: without the fix, creates M*N + M*N*K = 1,010,000 Path objects (~80 MB)` and the purpose of each node group. Removing them makes the test harder to understand for future contributors. Please revert the comment removals from `denseGraphDoesNotOom`, `autoSelectionResolvesConflictsCorrectly`, and `defaultConfigUsesAutoSelection`.
##########
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictResolver.java:
##########
@@ -254,18 +255,76 @@ public DependencyNode transformGraph(DependencyNode node, DependencyGraphTransfo
throws RepositoryException {
String cf = ConfigUtils.getString(
context.getSession(), DEFAULT_CONFLICT_RESOLVER_IMPL, CONFIG_PROP_CONFLICT_RESOLVER_IMPL);
+
ConflictResolver delegate;
- if (AUTO_CONFLICT_RESOLVER.equals(cf) || CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
+
+ if (AUTO_CONFLICT_RESOLVER.equals(cf)) {
+ delegate = selectConflictResolver(node, context);
+ } else if (CLASSIC_CONFLICT_RESOLVER.equals(cf)) {
delegate = new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else if (PATH_CONFLICT_RESOLVER.equals(cf)) {
delegate = new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
} else {
throw new IllegalArgumentException("Unknown conflict resolver: " + cf + "; known are "
+ Arrays.asList(AUTO_CONFLICT_RESOLVER, PATH_CONFLICT_RESOLVER, CLASSIC_CONFLICT_RESOLVER));
}
+
return delegate.transformGraph(node, context);
}
+ /**
+ * Automatically selects the conflict resolver based on the estimated memory requirements.
+ * PathConflictResolver is used for dependency trees that fit within the memory threshold,
+ * while ClassicConflictResolver is used for larger trees.
+ */
+ private ConflictResolver selectConflictResolver(DependencyNode node, DependencyGraphTransformationContext context)
+ throws RepositoryException {
+
+ if (context.get(TransformationContextKeys.SORTED_CONFLICT_IDS) == null) {
+ new ConflictIdSorter().transformGraph(node, context);
+ }
+
+ Runtime rt = Runtime.getRuntime();
+ long available = rt.maxMemory() - (rt.totalMemory() - rt.freeMemory());
+
+ // Estimate the maximum number of Path tree nodes that would fit in 25% of available heap.
+ // Each Path object costs ~200 bytes (object header + fields + children list entry).
+ int maxPathNodes = (int) Math.min(available / (4L * 200), Integer.MAX_VALUE);
+
+ // Walk the dependency tree to count total nodes (including diamond-expanded duplicates).
+ // The Path tree mirrors this structure, so the count directly reflects Path tree size.
+ // Use early-exit: stop counting once we exceed the threshold.
+ if (treeExceedsThreshold(node, maxPathNodes)) {
+ return new ClassicConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
+ } else {
+ return new PathConflictResolver(versionSelector, scopeSelector, optionalitySelector, scopeDeriver);
+ }
Review Comment:
ā ļø **Heuristic no longer matches PathConflictResolver behavior.** `treeExceedsThreshold` counts shared nodes multiple times (no visited set), mirroring the *old* PathConflictResolver expansion. After PR #2153, PathConflictResolver uses depth-bounded expansion and does NOT re-traverse subtrees of nodes already expanded at a shallower depth. The count from `treeExceedsThreshold` now **overestimates** PathConflictResolver's actual memory usage, causing unnecessary fallback to `ClassicConflictResolver` ā exactly the situation auto-selection was supposed to avoid.
##########
maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/transformer/ConflictResolverTest.java:
##########
@@ -860,6 +857,33 @@ void defaultConfigUsesAutoSelection() throws RepositoryException {
assertSame(baz1Node, fooNode.getChildren().get(1));
}
+ /**
+ * Verifies that tree threshold checking stops as soon as the number of visited nodes
+ * exceeds the configured threshold.
+ */
+ @org.junit.jupiter.api.Test
+ void treeThresholdStopsEarly() throws Exception {
+ ConflictResolver delegating = new ConflictResolver(
+ new NearestVersionSelector(),
+ new JavaScopeSelector(),
+ new SimpleOptionalitySelector(),
+ new JavaScopeDeriver());
+
+ DependencyNode root = makeDependencyNode("some-group", "root", "1.0");
+ DependencyNode child = makeDependencyNode("some-group", "child", "1.0");
+ DependencyNode grandChild = makeDependencyNode("some-group", "grand-child", "1.0");
+
+ root.setChildren(mutableList(child));
Review Comment:
š” **Reflection-based test is fragile.** Using `setAccessible(true)` to test a `private` method couples the test to an implementation detail. If the method is renamed, moved, or its signature changes, this test breaks silently at runtime rather than at compile time.
Consider either:
- Making `treeExceedsThreshold` package-private (it's a pure utility with no side effects)
- Testing the behavior through the public API instead (verify that `auto` config selects the expected resolver for small vs large graphs)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] [MRESOLVER-2076] Fix auto conflict resolver selection [maven-resolver]
Posted by "jiteshkhatri11 (via GitHub)" <gi...@apache.org>.
jiteshkhatri11 commented on PR #2132:
URL: https://github.com/apache/maven-resolver/pull/2132#issuecomment-5853702028
Thanks @cstamas. I rebased #2132 onto the current `master`, including the changes from #2153, and re-ran the `ConflictResolverTest` suite successfully.
Since #2153 addresses the PathConflictResolver memory issue that was blocking the previous auto-selection approach, Iād like to confirm whether you still want #2132 to reintroduce the automatic selection between PathConflictResolver and ClassicConflictResolver.
If it is no longer needed after #2153, Iām happy to close this PR.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org