From 0873e99ebc7cecf072bf2384a0ff6c499c4288a4 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 27 May 2026 09:41:23 +0200 Subject: [PATCH] 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 --- .../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 0b7fac393bf8..0dc5a7d0f044 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 , REP extends Result> REP request(REQ req, Fu @SuppressWarnings("unchecked") public , REP extends Result> List requests( List reqs, Function, List> supplier) { - final Map nonCachedResults = new HashMap<>(); + final Map nonCachedResults = new IdentityHashMap<>(); List> allResults = new ArrayList<>(reqs.size()); Function individualSupplier = req -> {