You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/06/07 09:50:05 UTC

(maven-resolver) 04/06: Fix WeakInternPool — synchronize compute on map

This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch gnodet/thread-safety-fixes
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git

commit 5b346ba794ca873ce88d241cc4ed392288a706ce
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sun Jun 7 09:45:45 2026 +0000

    Fix WeakInternPool — synchronize compute on map
    
    Collections.synchronizedMap does not make compute() atomic; the
    default Map.compute implementation performs a non-atomic read-modify
    sequence, risking concurrent structural modification of the underlying
    WeakHashMap.
    
    Wrap the compute() call in synchronized(map) to use the same monitor
    that synchronizedMap uses internally.
    
    Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
 .../aether/internal/impl/collect/DataPool.java     | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java
index 2e4e20765..958959035 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java
@@ -566,17 +566,19 @@ public final class DataPool {
         @SuppressWarnings("unchecked")
         public V intern(K key, V value) {
             Object[] result = new Object[1];
-            map.compute(key, (k, existingRef) -> {
-                if (existingRef != null) {
-                    V pooled = existingRef.get();
-                    if (pooled != null) {
-                        result[0] = pooled;
-                        return existingRef;
+            synchronized (map) {
+                map.compute(key, (k, existingRef) -> {
+                    if (existingRef != null) {
+                        V pooled = existingRef.get();
+                        if (pooled != null) {
+                            result[0] = pooled;
+                            return existingRef;
+                        }
                     }
-                }
-                result[0] = value;
-                return new WeakReference<>(value);
-            });
+                    result[0] = value;
+                    return new WeakReference<>(value);
+                });
+            }
             return (V) result[0];
         }
     }