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 2022/11/09 13:13:27 UTC
[maven] branch master updated: [MNG-7583] Allow concurrent access to the MavenPluginManager (#855)
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push:
new dfcf5791f [MNG-7583] Allow concurrent access to the MavenPluginManager (#855)
dfcf5791f is described below
commit dfcf5791fcc92ab82fc0cdb9f14aa372140c7a08
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Nov 9 14:13:18 2022 +0100
[MNG-7583] Allow concurrent access to the MavenPluginManager (#855)
---
.../maven/plugin/DefaultPluginDescriptorCache.java | 41 ++++++++++++++++++-
.../maven/plugin/DefaultPluginRealmCache.java | 32 +++++++++++++++
.../apache/maven/plugin/PluginDescriptorCache.java | 10 +++++
.../org/apache/maven/plugin/PluginRealmCache.java | 9 +++++
.../plugin/internal/DefaultMavenPluginManager.java | 46 ++++++++++------------
5 files changed, 110 insertions(+), 28 deletions(-)
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java
index 557026362..9e78b3c9b 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java
@@ -20,10 +20,10 @@ package org.apache.maven.plugin;
*/
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -55,7 +55,7 @@ public class DefaultPluginDescriptorCache
implements PluginDescriptorCache
{
- private Map<Key, PluginDescriptor> descriptors = new HashMap<>( 128 );
+ private Map<Key, PluginDescriptor> descriptors = new ConcurrentHashMap<>( 128 );
public void flush()
{
@@ -72,6 +72,43 @@ public class DefaultPluginDescriptorCache
return clone( descriptors.get( cacheKey ) );
}
+ @Override
+ public PluginDescriptor get( Key key, PluginDescriptorSupplier supplier )
+ throws PluginDescriptorParsingException, PluginResolutionException, InvalidPluginDescriptorException
+ {
+ try
+ {
+ return clone( descriptors.computeIfAbsent( key, k ->
+ {
+ try
+ {
+ return clone( supplier.load() );
+ }
+ catch ( PluginDescriptorParsingException | PluginResolutionException
+ | InvalidPluginDescriptorException e )
+ {
+ throw new RuntimeException( e );
+ }
+ } ) );
+ }
+ catch ( RuntimeException e )
+ {
+ if ( e.getCause() instanceof PluginDescriptorParsingException )
+ {
+ throw (PluginDescriptorParsingException) e.getCause();
+ }
+ if ( e.getCause() instanceof PluginResolutionException )
+ {
+ throw (PluginResolutionException) e.getCause();
+ }
+ if ( e.getCause() instanceof InvalidPluginDescriptorException )
+ {
+ throw (InvalidPluginDescriptorException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
public void put( Key cacheKey, PluginDescriptor pluginDescriptor )
{
descriptors.put( cacheKey, clone( pluginDescriptor ) );
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java
index fef5fe1d1..687cb9357 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java
@@ -159,6 +159,38 @@ public class DefaultPluginRealmCache
return cache.get( key );
}
+ @Override
+ public CacheRecord get( Key key, PluginRealmSupplier supplier )
+ throws PluginResolutionException, PluginContainerException
+ {
+ try
+ {
+ return cache.computeIfAbsent( key, k ->
+ {
+ try
+ {
+ return supplier.load();
+ }
+ catch ( PluginResolutionException | PluginContainerException e )
+ {
+ throw new RuntimeException( e );
+ }
+ } );
+ }
+ catch ( RuntimeException e )
+ {
+ if ( e.getCause() instanceof PluginResolutionException )
+ {
+ throw (PluginResolutionException) e.getCause();
+ }
+ if ( e.getCause() instanceof PluginContainerException )
+ {
+ throw (PluginContainerException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
public CacheRecord put( Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts )
{
Objects.requireNonNull( pluginRealm, "pluginRealm cannot be null" );
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java
index 08b4f1bc3..646b506d2 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java
@@ -47,12 +47,22 @@ public interface PluginDescriptorCache
// marker interface for cache keys
}
+ @FunctionalInterface
+ interface PluginDescriptorSupplier
+ {
+ PluginDescriptor load()
+ throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException;
+ }
+
Key createKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session );
void put( Key key, PluginDescriptor pluginDescriptor );
PluginDescriptor get( Key key );
+ PluginDescriptor get( Key key, PluginDescriptorSupplier supplier )
+ throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException;
+
void flush();
}
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java
index 78c3ae6f3..fecfaccfb 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java
@@ -74,12 +74,21 @@ public interface PluginRealmCache
// marker interface for cache keys
}
+ @FunctionalInterface
+ interface PluginRealmSupplier
+ {
+ CacheRecord load() throws PluginResolutionException, PluginContainerException;
+ }
+
Key createKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
RepositorySystemSession session );
CacheRecord get( Key key );
+ CacheRecord get( Key key, PluginRealmSupplier supplier )
+ throws PluginResolutionException, PluginContainerException;
+
CacheRecord put( Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts );
void flush();
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
index 5496eef14..8fdfb3e9a 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
@@ -184,31 +184,29 @@ public class DefaultMavenPluginManager
this.prerequisitesCheckers = prerequisitesCheckers;
}
- public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories,
- RepositorySystemSession session )
+ public PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException
{
PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey( plugin, repositories, session );
- PluginDescriptor pluginDescriptor = pluginDescriptorCache.get( cacheKey );
-
- if ( pluginDescriptor == null )
+ PluginDescriptor pluginDescriptor = pluginDescriptorCache.get( cacheKey, () ->
{
org.eclipse.aether.artifact.Artifact artifact =
pluginDependenciesResolver.resolve( plugin, repositories, session );
Artifact pluginArtifact = RepositoryUtils.toArtifact( artifact );
- pluginDescriptor = extractPluginDescriptor( pluginArtifact, plugin );
+ PluginDescriptor descriptor = extractPluginDescriptor( pluginArtifact, plugin );
- if ( StringUtils.isBlank( pluginDescriptor.getRequiredMavenVersion() ) )
+ if ( StringUtils.isBlank( descriptor.getRequiredMavenVersion() ) )
{
// only take value from underlying POM if plugin descriptor has no explicit Maven requirement
- pluginDescriptor.setRequiredMavenVersion( artifact.getProperty( "requiredMavenVersion", null ) );
+ descriptor.setRequiredMavenVersion( artifact.getProperty( "requiredMavenVersion", null ) );
}
- pluginDescriptorCache.put( cacheKey, pluginDescriptor );
- }
+ return descriptor;
+ } );
pluginDescriptor.setPlugin( plugin );
@@ -345,8 +343,8 @@ public class DefaultMavenPluginManager
}
}
- public synchronized void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session,
- ClassLoader parent, List<String> imports, DependencyFilter filter )
+ public void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session,
+ ClassLoader parent, List<String> imports, DependencyFilter filter )
throws PluginResolutionException, PluginContainerException
{
Plugin plugin = pluginDescriptor.getPlugin();
@@ -386,23 +384,19 @@ public class DefaultMavenPluginManager
project.getRemotePluginRepositories(),
session.getRepositorySession() );
- PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get( cacheKey );
-
- if ( cacheRecord != null )
- {
- pluginDescriptor.setClassRealm( cacheRecord.getRealm() );
- pluginDescriptor.setArtifacts( new ArrayList<>( cacheRecord.getArtifacts() ) );
- for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
- {
- componentDescriptor.setRealm( cacheRecord.getRealm() );
- }
- }
- else
+ PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get( cacheKey, () ->
{
createPluginRealm( pluginDescriptor, session, parent, foreignImports, filter );
- cacheRecord =
- pluginRealmCache.put( cacheKey, pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() );
+ return new PluginRealmCache.CacheRecord(
+ pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() );
+ } );
+
+ pluginDescriptor.setClassRealm( cacheRecord.getRealm() );
+ pluginDescriptor.setArtifacts( new ArrayList<>( cacheRecord.getArtifacts() ) );
+ for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
+ {
+ componentDescriptor.setRealm( cacheRecord.getRealm() );
}
pluginRealmCache.register( project, cacheKey, cacheRecord );