Refactor MavenSession#getPluginContext to be thread safe (#575)
This PR introduce no API change, merely refactors MavenSession
getPluginContext method to truly thread-safe.
Also added Javadoc to affected field and method.
diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
index f8dbb03..c2f0c89 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
@@ -26,6 +26,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.RepositoryCache;
@@ -75,7 +76,13 @@
private boolean parallel;
- private final Map<String, Map<String, Map<String, Object>>> pluginContextsByProjectAndPluginKey =
+ /**
+ * Plugin context keyed by project ({@link MavenProject#getId()}) and by plugin lookup key
+ * ({@link PluginDescriptor#getPluginLookupKey()}). Plugin contexts itself are mappings of {@link String} keys to
+ * {@link Object} values.
+ */
+ @SuppressWarnings( "checkstyle:linelength" )
+ private final ConcurrentMap<String, ConcurrentMap<String, ConcurrentMap<String, Object>>> pluginContextsByProjectAndPluginKey =
new ConcurrentHashMap<>();
@@ -192,31 +199,25 @@
// Backward compat
+
+ /**
+ * Returns the plugin context for given key ({@link PluginDescriptor#getPluginLookupKey()} and
+ * {@link MavenProject}, never returns {@code null} as if context not present, creates it.
+ *
+ * <strong>Implementation note:</strong> while this method return type is {@link Map}, the returned map instance
+ * implements {@link ConcurrentMap} as well.
+ *
+ */
public Map<String, Object> getPluginContext( PluginDescriptor plugin, MavenProject project )
{
String projectKey = project.getId();
- Map<String, Map<String, Object>> pluginContextsByKey = pluginContextsByProjectAndPluginKey.get( projectKey );
-
- if ( pluginContextsByKey == null )
- {
- pluginContextsByKey = new ConcurrentHashMap<>();
-
- pluginContextsByProjectAndPluginKey.put( projectKey, pluginContextsByKey );
- }
+ ConcurrentMap<String, ConcurrentMap<String, Object>> pluginContextsByKey = pluginContextsByProjectAndPluginKey
+ .computeIfAbsent( projectKey, k -> new ConcurrentHashMap<>() );
String pluginKey = plugin.getPluginLookupKey();
- Map<String, Object> pluginContext = pluginContextsByKey.get( pluginKey );
-
- if ( pluginContext == null )
- {
- pluginContext = new ConcurrentHashMap<>();
-
- pluginContextsByKey.put( pluginKey, pluginContext );
- }
-
- return pluginContext;
+ return pluginContextsByKey.computeIfAbsent( pluginKey, k -> new ConcurrentHashMap<>() );
}
public ProjectDependencyGraph getProjectDependencyGraph()