This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch maven-3.9.x
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/maven-3.9.x by this push:
new 9037805f7 [MNG-7583] Allow concurrent access to the MavenPluginManager
(#1001)
9037805f7 is described below
commit 9037805f775e1034b90e614eaf2348a7c437410c
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Mar 1 11:31:29 2023 +0100
[MNG-7583] Allow concurrent access to the MavenPluginManager (#1001)
* [MNG-7583] Allow concurrent access to the MavenPluginManager (#855)
* Add a default method to avoid breaking the api
---
.../maven/plugin/DefaultPluginDescriptorCache.java | 31 +++++++++++++++--
.../maven/plugin/DefaultPluginRealmCache.java | 22 ++++++++++++
.../apache/maven/plugin/PluginDescriptorCache.java | 16 +++++++++
.../org/apache/maven/plugin/PluginRealmCache.java | 15 +++++++++
.../plugin/internal/DefaultMavenPluginManager.java | 39 +++++++++++-----------
5 files changed, 101 insertions(+), 22 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 d0a2e8374..8278cba9e 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
@@ -19,10 +19,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 org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.ArtifactUtils;
@@ -49,7 +49,7 @@ import org.eclipse.aether.repository.WorkspaceRepository;
@Component(role = PluginDescriptorCache.class)
public class DefaultPluginDescriptorCache implements PluginDescriptorCache {
- private Map<Key, PluginDescriptor> descriptors = new HashMap<>(128);
+ private Map<Key, PluginDescriptor> descriptors = new
ConcurrentHashMap<>(128);
public void flush() {
descriptors.clear();
@@ -63,6 +63,33 @@ public class DefaultPluginDescriptorCache implements
PluginDescriptorCache {
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 0647235c4..10321374b 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
@@ -147,6 +147,28 @@ public class DefaultPluginRealmCache implements
PluginRealmCache, Disposable {
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");
Objects.requireNonNull(pluginArtifacts, "pluginArtifacts 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 ef33da894..763d4af16 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
@@ -44,11 +44,27 @@ 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);
+ default PluginDescriptor get(Key key, PluginDescriptorSupplier supplier)
+ throws PluginResolutionException,
PluginDescriptorParsingException, InvalidPluginDescriptorException {
+ PluginDescriptor pd = get(key);
+ if (pd == null) {
+ pd = supplier.load();
+ put(key, pd);
+ }
+ return pd;
+ }
+
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 b8f786a08..bf655efc3 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
@@ -67,6 +67,11 @@ public interface PluginRealmCache {
// marker interface for cache keys
}
+ @FunctionalInterface
+ interface PluginRealmSupplier {
+ CacheRecord load() throws PluginResolutionException,
PluginContainerException;
+ }
+
Key createKey(
Plugin plugin,
ClassLoader parentRealm,
@@ -77,6 +82,16 @@ public interface PluginRealmCache {
CacheRecord get(Key key);
+ default CacheRecord get(Key key, PluginRealmSupplier supplier)
+ throws PluginResolutionException, PluginContainerException {
+ CacheRecord cr = get(key);
+ if (cr == null) {
+ CacheRecord tcr = supplier.load();
+ cr = put(key, tcr.getRealm(), tcr.getArtifacts());
+ }
+ return cr;
+ }
+
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 0161e8c48..e652e4c77 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
@@ -168,25 +168,26 @@ public class DefaultMavenPluginManager implements
MavenPluginManager {
private PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
- public synchronized PluginDescriptor getPluginDescriptor(
+ 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);
-
pluginDescriptor.setRequiredMavenVersion(artifact.getProperty("requiredMavenVersion",
null));
+ if (StringUtils.isBlank(descriptor.getRequiredMavenVersion())) {
+ // only take value from underlying POM if plugin descriptor
has no explicit Maven requirement
+
descriptor.setRequiredMavenVersion(artifact.getProperty("requiredMavenVersion",
null));
+ }
- pluginDescriptorCache.put(cacheKey, pluginDescriptor);
- }
+ return descriptor;
+ });
pluginDescriptor.setPlugin(plugin);
@@ -289,7 +290,7 @@ public class DefaultMavenPluginManager implements
MavenPluginManager {
}
}
- public synchronized void setupPluginRealm(
+ public void setupPluginRealm(
PluginDescriptor pluginDescriptor,
MavenSession session,
ClassLoader parent,
@@ -330,19 +331,17 @@ public class DefaultMavenPluginManager implements
MavenPluginManager {
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);