This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch fix/identity-hashmap-request-cache in repository https://gitbox.apache.org/repos/asf/maven.git
commit 0873e99ebc7cecf072bf2384a0ff6c499c4288a4 Author: Guillaume Nodet <[email protected]> AuthorDate: Wed May 27 09:41:23 2026 +0200 Fix deadlock in AbstractRequestCache.requests() due to unstable hashCode The `requests()` method uses a HashMap to coordinate batch results between the batch supplier and the individual CachingSupplier instances. When a request object's hashCode() changes between HashMap.put() and HashMap.containsKey() (e.g., because ResolverRequest includes a RequestTrace with mutable ModelBuilderRequest data), the key is stored in one bucket but looked up in another, causing containsKey() to return false. The individualSupplier then waits forever for a result that is already in the map but unreachable. Switch to IdentityHashMap which uses System.identityHashCode() and reference equality (==), both of which are stable regardless of mutable object state. This is safe because the code always uses the same object reference for put and get. Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../main/java/org/apache/maven/impl/cache/AbstractRequestCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/AbstractRequestCache.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/AbstractRequestCache.java index 0b7fac393b..0dc5a7d0f0 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/AbstractRequestCache.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/cache/AbstractRequestCache.java @@ -19,7 +19,7 @@ package org.apache.maven.impl.cache; import java.util.ArrayList; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -85,7 +85,7 @@ public <REQ extends Request<?>, REP extends Result<REQ>> REP request(REQ req, Fu @SuppressWarnings("unchecked") public <REQ extends Request<?>, REP extends Result<REQ>> List<REP> requests( List<REQ> reqs, Function<List<REQ>, List<REP>> supplier) { - final Map<REQ, Object> nonCachedResults = new HashMap<>(); + final Map<REQ, Object> nonCachedResults = new IdentityHashMap<>(); List<RequestResult<REQ, REP>> allResults = new ArrayList<>(reqs.size()); Function<REQ, REP> individualSupplier = req -> {
