diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
index cda855f07..49be297e2 100644
--- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
+++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
@@ -70,7 +70,6 @@
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.plugin.ExtensionRealmCache;
-import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.PluginArtifactsCache;
import org.apache.maven.plugin.PluginRealmCache;
import org.apache.maven.plugin.version.PluginVersionResolver;
@@ -105,7 +104,6 @@
import org.mvndaemon.mvnd.logging.smart.LoggingExecutionListener;
import org.mvndaemon.mvnd.logging.smart.LoggingOutputStream;
import org.mvndaemon.mvnd.plugin.CachingPluginVersionResolver;
-import org.mvndaemon.mvnd.plugin.CliMavenPluginManager;
import org.mvndaemon.mvnd.transfer.DaemonMavenTransferListener;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
@@ -527,7 +525,6 @@ protected void configure() {
bind(PluginArtifactsCache.class).to(InvalidatingPluginArtifactsCache.class);
bind(PluginRealmCache.class).to(InvalidatingPluginRealmCache.class);
bind(ProjectArtifactsCache.class).to(InvalidatingProjectArtifactsCache.class);
- bind(MavenPluginManager.class).to(CliMavenPluginManager.class);
bind(PluginVersionResolver.class).to(CachingPluginVersionResolver.class);
}
});
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/cache/invalidating/InvalidatingPluginRealmCache.java b/daemon/src/main/java/org/mvndaemon/mvnd/cache/invalidating/InvalidatingPluginRealmCache.java
index 6817d8541..d832f27bc 100644
--- a/daemon/src/main/java/org/mvndaemon/mvnd/cache/invalidating/InvalidatingPluginRealmCache.java
+++ b/daemon/src/main/java/org/mvndaemon/mvnd/cache/invalidating/InvalidatingPluginRealmCache.java
@@ -40,11 +40,6 @@
@Priority(10)
public class InvalidatingPluginRealmCache extends DefaultPluginRealmCache {
- @FunctionalInterface
- public interface PluginRealmSupplier {
- CacheRecord load() throws PluginResolutionException, PluginContainerException;
- }
-
protected static class Record implements org.mvndaemon.mvnd.cache.CacheRecord {
final CacheRecord record;
@@ -83,6 +78,7 @@ public CacheRecord get(Key key) {
return r != null ? r.record : null;
}
+ @Override
public CacheRecord get(Key key, PluginRealmSupplier supplier)
throws PluginResolutionException, PluginContainerException {
try {
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java
deleted file mode 100644
index 9e3b7f836..000000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/CliMavenPluginManager.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.mvndaemon.mvnd.plugin;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.classrealm.ClassRealmManager;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
-import org.apache.maven.model.Plugin;
-import org.apache.maven.plugin.ContextEnabled;
-import org.apache.maven.plugin.DebugConfigurationListener;
-import org.apache.maven.plugin.ExtensionRealmCache;
-import org.apache.maven.plugin.InvalidPluginDescriptorException;
-import org.apache.maven.plugin.MavenPluginManager;
-import org.apache.maven.plugin.Mojo;
-import org.apache.maven.plugin.MojoExecution;
-import org.apache.maven.plugin.MojoNotFoundException;
-import org.apache.maven.plugin.PluginArtifactsCache;
-import org.apache.maven.plugin.PluginConfigurationException;
-import org.apache.maven.plugin.PluginContainerException;
-import org.apache.maven.plugin.PluginDescriptorCache;
-import org.apache.maven.plugin.PluginDescriptorParsingException;
-import org.apache.maven.plugin.PluginIncompatibleException;
-import org.apache.maven.plugin.PluginManagerException;
-import org.apache.maven.plugin.PluginParameterException;
-import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
-import org.apache.maven.plugin.PluginRealmCache;
-import org.apache.maven.plugin.PluginResolutionException;
-import org.apache.maven.plugin.descriptor.MojoDescriptor;
-import org.apache.maven.plugin.descriptor.Parameter;
-import org.apache.maven.plugin.descriptor.PluginDescriptor;
-import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
-import org.apache.maven.plugin.internal.MojoLogWrapper;
-import org.apache.maven.plugin.internal.PluginDependenciesResolver;
-import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
-import org.apache.maven.plugin.version.PluginVersionRequest;
-import org.apache.maven.plugin.version.PluginVersionResolutionException;
-import org.apache.maven.plugin.version.PluginVersionResolver;
-import org.apache.maven.project.ExtensionDescriptor;
-import org.apache.maven.project.ExtensionDescriptorBuilder;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.rtinfo.RuntimeInformation;
-import org.apache.maven.session.scope.internal.SessionScopeModule;
-import org.codehaus.plexus.DefaultPlexusContainer;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.classworlds.realm.ClassRealm;
-import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
-import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
-import org.codehaus.plexus.component.configurator.ComponentConfigurator;
-import org.codehaus.plexus.component.configurator.ConfigurationListener;
-import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
-import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
-import org.codehaus.plexus.component.repository.ComponentDescriptor;
-import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.configuration.PlexusConfiguration;
-import org.codehaus.plexus.configuration.PlexusConfigurationException;
-import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
-import org.codehaus.plexus.logging.LoggerManager;
-import org.codehaus.plexus.util.ReaderFactory;
-import org.codehaus.plexus.util.StringUtils;
-import org.codehaus.plexus.util.xml.Xpp3Dom;
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.graph.DependencyFilter;
-import org.eclipse.aether.graph.DependencyNode;
-import org.eclipse.aether.repository.RemoteRepository;
-import org.eclipse.aether.util.filter.AndDependencyFilter;
-import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
-import org.eclipse.sisu.Priority;
-import org.eclipse.sisu.Typed;
-import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginDescriptorCache;
-import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginRealmCache;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/*
- * gnodet: This file is based on maven DefaultMavenPluginManager and changed in order
- * to better support parallel builds. See https://github.com/apache/maven-mvnd/issues/310
- */
-/**
- * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such
- * that the plugins/mojos can be used in arbitrary contexts. In particular, the mojos can be used for ordinary build
- * plugins as well as special purpose plugins like reports.
- *
- * @author Benjamin Bentmann
- * @since 3.0
- */
-@Singleton
-@Named
-@Priority(10)
-@Typed(MavenPluginManager.class)
-public class CliMavenPluginManager implements MavenPluginManager {
-
- /**
- *
- * PluginId => ExtensionRealmCache.CacheRecord map MavenProject context value key. The map is used to ensure the
- * same class realm is used to load build extensions and load mojos for extensions=true plugins.
- *
- * Note: This is part of internal implementation and may be changed or removed without notice
- *
- * @since 3.3.0
- */
- public static final String KEY_EXTENSIONS_REALMS = CliMavenPluginManager.class.getName() + "/extensionsRealms";
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- @Inject
- private LoggerManager loggerManager;
-
- @Inject
- private PlexusContainer container;
-
- @Inject
- private ClassRealmManager classRealmManager;
-
- @Inject
- private InvalidatingPluginDescriptorCache pluginDescriptorCache;
-
- @Inject
- private InvalidatingPluginRealmCache pluginRealmCache;
-
- @Inject
- private PluginDependenciesResolver pluginDependenciesResolver;
-
- @Inject
- private RuntimeInformation runtimeInformation;
-
- @Inject
- private ExtensionRealmCache extensionRealmCache;
-
- @Inject
- private PluginVersionResolver pluginVersionResolver;
-
- @Inject
- private PluginArtifactsCache pluginArtifactsCache;
-
- private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
-
- private PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
-
- public PluginDescriptor getPluginDescriptor(
- Plugin plugin, List repositories, RepositorySystemSession session)
- throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException {
- PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey(plugin, repositories, session);
-
- PluginDescriptor pluginDescriptor = pluginDescriptorCache.get(cacheKey, () -> {
- org.eclipse.aether.artifact.Artifact artifact =
- pluginDependenciesResolver.resolve(plugin, repositories, session);
-
- Artifact pluginArtifact = RepositoryUtils.toArtifact(artifact);
-
- PluginDescriptor descriptor = extractPluginDescriptor(pluginArtifact, plugin);
-
- descriptor.setRequiredMavenVersion(artifact.getProperty("requiredMavenVersion", null));
-
- return descriptor;
- });
-
- pluginDescriptor.setPlugin(plugin);
-
- return pluginDescriptor;
- }
-
- private PluginDescriptor extractPluginDescriptor(Artifact pluginArtifact, Plugin plugin)
- throws PluginDescriptorParsingException, InvalidPluginDescriptorException {
- PluginDescriptor pluginDescriptor = null;
-
- File pluginFile = pluginArtifact.getFile();
-
- try {
- if (pluginFile.isFile()) {
- try (JarFile pluginJar = new JarFile(pluginFile, false)) {
- ZipEntry pluginDescriptorEntry = pluginJar.getEntry(getPluginDescriptorLocation());
-
- if (pluginDescriptorEntry != null) {
- InputStream is = pluginJar.getInputStream(pluginDescriptorEntry);
-
- pluginDescriptor = parsePluginDescriptor(is, plugin, pluginFile.getAbsolutePath());
- }
- }
- } else {
- File pluginXml = new File(pluginFile, getPluginDescriptorLocation());
-
- if (pluginXml.isFile()) {
- try (InputStream is = new BufferedInputStream(new FileInputStream(pluginXml))) {
- pluginDescriptor = parsePluginDescriptor(is, plugin, pluginXml.getAbsolutePath());
- }
- }
- }
-
- if (pluginDescriptor == null) {
- throw new IOException("No plugin descriptor found at " + getPluginDescriptorLocation());
- }
- } catch (IOException e) {
- throw new PluginDescriptorParsingException(plugin, pluginFile.getAbsolutePath(), e);
- }
-
- List errors = new ArrayList<>();
- validate(pluginArtifact, pluginDescriptor, errors);
-
- if (!errors.isEmpty()) {
- throw new InvalidPluginDescriptorException(
- "Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", errors);
- }
-
- pluginDescriptor.setPluginArtifact(pluginArtifact);
-
- return pluginDescriptor;
- }
-
- private void validate(Artifact pluginArtifact, PluginDescriptor pluginDescriptor, List errors) {
- if (!pluginArtifact.getGroupId().equals(pluginDescriptor.getGroupId())) {
- errors.add("Plugin's descriptor contains the wrong group ID: " + pluginDescriptor.getGroupId());
- }
-
- if (!pluginArtifact.getArtifactId().equals(pluginDescriptor.getArtifactId())) {
- errors.add("Plugin's descriptor contains the wrong artifact ID: " + pluginDescriptor.getArtifactId());
- }
-
- if (!pluginArtifact.getBaseVersion().equals(pluginDescriptor.getVersion())) {
- errors.add("Plugin's descriptor contains the wrong version: " + pluginDescriptor.getVersion());
- }
- }
-
- private String getPluginDescriptorLocation() {
- return "META-INF/maven/plugin.xml";
- }
-
- private PluginDescriptor parsePluginDescriptor(InputStream is, Plugin plugin, String descriptorLocation)
- throws PluginDescriptorParsingException {
- try {
- Reader reader = ReaderFactory.newXmlReader(is);
-
- PluginDescriptor pluginDescriptor = builder.build(reader, descriptorLocation);
-
- return pluginDescriptor;
- } catch (IOException | PlexusConfigurationException e) {
- throw new PluginDescriptorParsingException(plugin, descriptorLocation, e);
- }
- }
-
- public MojoDescriptor getMojoDescriptor(
- Plugin plugin, String goal, List repositories, RepositorySystemSession session)
- throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
- InvalidPluginDescriptorException {
- PluginDescriptor pluginDescriptor = getPluginDescriptor(plugin, repositories, session);
-
- MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo(goal);
-
- if (mojoDescriptor == null) {
- throw new MojoNotFoundException(goal, pluginDescriptor);
- }
-
- return mojoDescriptor;
- }
-
- public void checkRequiredMavenVersion(PluginDescriptor pluginDescriptor) throws PluginIncompatibleException {
- String requiredMavenVersion = pluginDescriptor.getRequiredMavenVersion();
- if (StringUtils.isNotBlank(requiredMavenVersion)) {
- try {
- if (!runtimeInformation.isMavenVersion(requiredMavenVersion)) {
- throw new PluginIncompatibleException(
- pluginDescriptor.getPlugin(),
- "The plugin " + pluginDescriptor.getId() + " requires Maven version "
- + requiredMavenVersion);
- }
- } catch (RuntimeException e) {
- logger.warn("Could not verify plugin's Maven prerequisite: " + e.getMessage());
- }
- }
- }
-
- public void setupPluginRealm(
- PluginDescriptor pluginDescriptor,
- MavenSession session,
- ClassLoader parent,
- List imports,
- DependencyFilter filter)
- throws PluginResolutionException, PluginContainerException {
- Plugin plugin = pluginDescriptor.getPlugin();
- MavenProject project = session.getCurrentProject();
-
- if (plugin.isExtensions()) {
- ExtensionRealmCache.CacheRecord extensionRecord;
- try {
- RepositorySystemSession repositorySession = session.getRepositorySession();
- extensionRecord = setupExtensionsRealm(project, plugin, repositorySession);
- } catch (PluginManagerException e) {
- // extensions realm is expected to be fully setup at this point
- // any exception means a problem in maven code, not a user error
- throw new IllegalStateException(e);
- }
-
- ClassRealm pluginRealm = extensionRecord.getRealm();
- List pluginArtifacts = extensionRecord.getArtifacts();
-
- for (ComponentDescriptor> componentDescriptor : pluginDescriptor.getComponents()) {
- componentDescriptor.setRealm(pluginRealm);
- }
-
- pluginDescriptor.setClassRealm(pluginRealm);
- pluginDescriptor.setArtifacts(pluginArtifacts);
- } else {
- Map foreignImports = calcImports(project, parent, imports);
-
- PluginRealmCache.Key cacheKey = pluginRealmCache.createKey(
- plugin,
- parent,
- foreignImports,
- filter,
- project.getRemotePluginRepositories(),
- session.getRepositorySession());
-
- PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get(cacheKey, () -> {
- createPluginRealm(pluginDescriptor, session, parent, foreignImports, filter);
- return new PluginRealmCache.CacheRecord(
- pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts());
- });
-
- if (cacheRecord != null) {
- pluginDescriptor.setClassRealm(cacheRecord.getRealm());
- pluginDescriptor.setArtifacts(new ArrayList<>(cacheRecord.getArtifacts()));
- for (ComponentDescriptor> componentDescriptor : pluginDescriptor.getComponents()) {
- componentDescriptor.setRealm(cacheRecord.getRealm());
- }
- }
-
- pluginRealmCache.register(project, cacheKey, cacheRecord);
- }
- }
-
- private void createPluginRealm(
- PluginDescriptor pluginDescriptor,
- MavenSession session,
- ClassLoader parent,
- Map foreignImports,
- DependencyFilter filter)
- throws PluginResolutionException, PluginContainerException {
- Plugin plugin = Objects.requireNonNull(pluginDescriptor.getPlugin(), "pluginDescriptor.plugin cannot be null");
-
- Artifact pluginArtifact = Objects.requireNonNull(
- pluginDescriptor.getPluginArtifact(), "pluginDescriptor.pluginArtifact cannot be null");
-
- MavenProject project = session.getCurrentProject();
-
- final ClassRealm pluginRealm;
- final List pluginArtifacts;
-
- RepositorySystemSession repositorySession = session.getRepositorySession();
- DependencyFilter dependencyFilter = project.getExtensionDependencyFilter();
- dependencyFilter = AndDependencyFilter.newInstance(dependencyFilter, filter);
-
- DependencyNode root = pluginDependenciesResolver.resolve(
- plugin,
- RepositoryUtils.toArtifact(pluginArtifact),
- dependencyFilter,
- project.getRemotePluginRepositories(),
- repositorySession);
-
- PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
- root.accept(nlg);
-
- pluginArtifacts = toMavenArtifacts(root, nlg);
-
- if (parent == null) {
- parent = new URLClassLoader(new URL[0]);
- }
- pluginRealm = classRealmManager.createPluginRealm(
- plugin, parent, null, foreignImports, toAetherArtifacts(pluginArtifacts));
-
- discoverPluginComponents(pluginRealm, plugin, pluginDescriptor);
-
- pluginDescriptor.setClassRealm(pluginRealm);
- pluginDescriptor.setArtifacts(pluginArtifacts);
- }
-
- private void discoverPluginComponents(
- final ClassRealm pluginRealm, Plugin plugin, PluginDescriptor pluginDescriptor)
- throws PluginContainerException {
- try {
- if (pluginDescriptor != null) {
- for (ComponentDescriptor> componentDescriptor : pluginDescriptor.getComponents()) {
- componentDescriptor.setRealm(pluginRealm);
- container.addComponentDescriptor(componentDescriptor);
- }
- }
-
- ((DefaultPlexusContainer) container)
- .discoverComponents(
- pluginRealm, new SessionScopeModule(container), new MojoExecutionScopeModule(container));
- } catch (ComponentLookupException | CycleDetectedInComponentGraphException e) {
- throw new PluginContainerException(
- plugin,
- pluginRealm,
- "Error in component graph of plugin " + plugin.getId() + ": " + e.getMessage(),
- e);
- }
- }
-
- private List toAetherArtifacts(final List pluginArtifacts) {
- return new ArrayList<>(RepositoryUtils.toArtifacts(pluginArtifacts));
- }
-
- private List toMavenArtifacts(DependencyNode root, PreorderNodeListGenerator nlg) {
- List artifacts = new ArrayList<>(nlg.getNodes().size());
- RepositoryUtils.toArtifacts(artifacts, Collections.singleton(root), Collections.emptyList(), null);
- for (Iterator it = artifacts.iterator(); it.hasNext(); ) {
- Artifact artifact = it.next();
- if (artifact.getFile() == null) {
- it.remove();
- }
- }
- return Collections.unmodifiableList(artifacts);
- }
-
- private Map calcImports(MavenProject project, ClassLoader parent, List imports) {
- Map foreignImports = new HashMap<>();
-
- ClassLoader projectRealm = project.getClassRealm();
- if (projectRealm != null) {
- foreignImports.put("", projectRealm);
- } else {
- foreignImports.put("", classRealmManager.getMavenApiRealm());
- }
-
- if (parent != null && imports != null) {
- for (String parentImport : imports) {
- foreignImports.put(parentImport, parent);
- }
- }
-
- return foreignImports;
- }
-
- public T getConfiguredMojo(Class mojoInterface, MavenSession session, MojoExecution mojoExecution)
- throws PluginConfigurationException, PluginContainerException {
- MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
-
- PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
-
- ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
-
- if (logger.isDebugEnabled()) {
- logger.debug("Configuring mojo " + mojoDescriptor.getId() + " from plugin realm " + pluginRealm);
- }
-
- // We are forcing the use of the plugin realm for all lookups that might occur during
- // the lifecycle that is part of the lookup. Here we are specifically trying to keep
- // lookups that occur in contextualize calls in line with the right realm.
- ClassRealm oldLookupRealm = container.setLookupRealm(pluginRealm);
-
- ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(pluginRealm);
-
- try {
- T mojo;
-
- try {
- mojo = container.lookup(mojoInterface, mojoDescriptor.getRoleHint());
- } catch (ComponentLookupException e) {
- Throwable cause = e.getCause();
- while (cause != null
- && !(cause instanceof LinkageError)
- && !(cause instanceof ClassNotFoundException)) {
- cause = cause.getCause();
- }
-
- if ((cause instanceof NoClassDefFoundError) || (cause instanceof ClassNotFoundException)) {
- ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
- PrintStream ps = new PrintStream(os);
- ps.println("Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '"
- + pluginDescriptor.getId() + "'. A required class is missing: "
- + cause.getMessage());
- pluginRealm.display(ps);
-
- throw new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), cause);
- } else if (cause instanceof LinkageError) {
- ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
- PrintStream ps = new PrintStream(os);
- ps.println("Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '"
- + pluginDescriptor.getId() + "' due to an API incompatibility: "
- + e.getClass().getName() + ": " + cause.getMessage());
- pluginRealm.display(ps);
-
- throw new PluginContainerException(mojoDescriptor, pluginRealm, os.toString(), cause);
- }
-
- throw new PluginContainerException(
- mojoDescriptor,
- pluginRealm,
- "Unable to load the mojo '" + mojoDescriptor.getGoal()
- + "' (or one of its required components) from the plugin '"
- + pluginDescriptor.getId() + "'",
- e);
- }
-
- if (mojo instanceof ContextEnabled) {
- MavenProject project = session.getCurrentProject();
-
- Map pluginContext = session.getPluginContext(pluginDescriptor, project);
-
- if (pluginContext != null) {
- pluginContext.put("project", project);
-
- pluginContext.put("pluginDescriptor", pluginDescriptor);
-
- ((ContextEnabled) mojo).setPluginContext(pluginContext);
- }
- }
-
- if (mojo instanceof Mojo) {
- org.slf4j.Logger mojoLogger = LoggerFactory.getLogger(mojoDescriptor.getImplementation());
- ((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
- }
-
- Xpp3Dom dom = mojoExecution.getConfiguration();
-
- PlexusConfiguration pomConfiguration;
-
- if (dom == null) {
- pomConfiguration = new XmlPlexusConfiguration("configuration");
- } else {
- pomConfiguration = new XmlPlexusConfiguration(dom);
- }
-
- ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);
-
- populatePluginFields(mojo, mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator);
-
- return mojo;
- } finally {
- Thread.currentThread().setContextClassLoader(oldClassLoader);
- container.setLookupRealm(oldLookupRealm);
- }
- }
-
- private void populatePluginFields(
- Object mojo,
- MojoDescriptor mojoDescriptor,
- ClassRealm pluginRealm,
- PlexusConfiguration configuration,
- ExpressionEvaluator expressionEvaluator)
- throws PluginConfigurationException {
- ComponentConfigurator configurator = null;
-
- String configuratorId = mojoDescriptor.getComponentConfigurator();
-
- if (StringUtils.isEmpty(configuratorId)) {
- configuratorId = "basic";
- }
-
- try {
- // TODO could the configuration be passed to lookup and the configurator known to plexus via the descriptor
- // so that this method could entirely be handled by a plexus lookup?
- configurator = container.lookup(ComponentConfigurator.class, configuratorId);
-
- ConfigurationListener listener = new DebugConfigurationListener(logger);
-
- ValidatingConfigurationListener validator =
- new ValidatingConfigurationListener(mojo, mojoDescriptor, listener);
-
- logger.debug(
- "Configuring mojo '" + mojoDescriptor.getId() + "' with " + configuratorId + " configurator -->");
-
- configurator.configureComponent(mojo, configuration, expressionEvaluator, pluginRealm, validator);
-
- logger.debug("-- end configuration --");
-
- Collection missingParameters = validator.getMissingParameters();
- if (!missingParameters.isEmpty()) {
- if ("basic".equals(configuratorId)) {
- throw new PluginParameterException(mojoDescriptor, new ArrayList<>(missingParameters));
- } else {
- /*
- * NOTE: Other configurators like the map-oriented one don't call into the listener, so do it the
- * hard way.
- */
- validateParameters(mojoDescriptor, configuration, expressionEvaluator);
- }
- }
- } catch (ComponentConfigurationException e) {
- String message = "Unable to parse configuration of mojo " + mojoDescriptor.getId();
- if (e.getFailedConfiguration() != null) {
- message += " for parameter " + e.getFailedConfiguration().getName();
- }
- message += ": " + e.getMessage();
-
- throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), message, e);
- } catch (ComponentLookupException e) {
- throw new PluginConfigurationException(
- mojoDescriptor.getPluginDescriptor(),
- "Unable to retrieve component configurator " + configuratorId + " for configuration of mojo "
- + mojoDescriptor.getId(),
- e);
- } catch (NoClassDefFoundError e) {
- ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
- PrintStream ps = new PrintStream(os);
- ps.println("A required class was missing during configuration of mojo " + mojoDescriptor.getId() + ": "
- + e.getMessage());
- pluginRealm.display(ps);
-
- throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), os.toString(), e);
- } catch (LinkageError e) {
- ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
- PrintStream ps = new PrintStream(os);
- ps.println("An API incompatibility was encountered during configuration of mojo " + mojoDescriptor.getId()
- + ": " + e.getClass().getName() + ": " + e.getMessage());
- pluginRealm.display(ps);
-
- throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), os.toString(), e);
- } finally {
- if (configurator != null) {
- try {
- container.release(configurator);
- } catch (ComponentLifecycleException e) {
- logger.debug("Failed to release mojo configurator - ignoring.");
- }
- }
- }
- }
-
- private void validateParameters(
- MojoDescriptor mojoDescriptor, PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator)
- throws ComponentConfigurationException, PluginParameterException {
- if (mojoDescriptor.getParameters() == null) {
- return;
- }
-
- List invalidParameters = new ArrayList<>();
-
- for (Parameter parameter : mojoDescriptor.getParameters()) {
- if (!parameter.isRequired()) {
- continue;
- }
-
- Object value = null;
-
- PlexusConfiguration config = configuration.getChild(parameter.getName(), false);
- if (config != null) {
- String expression = config.getValue(null);
-
- try {
- value = expressionEvaluator.evaluate(expression);
-
- if (value == null) {
- value = config.getAttribute("default-value", null);
- }
- } catch (ExpressionEvaluationException e) {
- String msg = "Error evaluating the expression '" + expression + "' for configuration value '"
- + configuration.getName() + "'";
- throw new ComponentConfigurationException(configuration, msg, e);
- }
- }
-
- if (value == null && (config == null || config.getChildCount() <= 0)) {
- invalidParameters.add(parameter);
- }
- }
-
- if (!invalidParameters.isEmpty()) {
- throw new PluginParameterException(mojoDescriptor, invalidParameters);
- }
- }
-
- public void releaseMojo(Object mojo, MojoExecution mojoExecution) {
- if (mojo != null) {
- try {
- container.release(mojo);
- } catch (ComponentLifecycleException e) {
- String goalExecId = mojoExecution.getGoal();
-
- if (mojoExecution.getExecutionId() != null) {
- goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}";
- }
-
- logger.debug("Error releasing mojo for " + goalExecId, e);
- }
- }
- }
-
- public ExtensionRealmCache.CacheRecord setupExtensionsRealm(
- MavenProject project, Plugin plugin, RepositorySystemSession session) throws PluginManagerException {
- @SuppressWarnings("unchecked")
- Map pluginRealms =
- (Map) project.getContextValue(KEY_EXTENSIONS_REALMS);
- if (pluginRealms == null) {
- pluginRealms = new HashMap<>();
- project.setContextValue(KEY_EXTENSIONS_REALMS, pluginRealms);
- }
-
- final String pluginKey = plugin.getId();
-
- ExtensionRealmCache.CacheRecord extensionRecord = pluginRealms.get(pluginKey);
- if (extensionRecord != null) {
- return extensionRecord;
- }
-
- final List repositories = project.getRemotePluginRepositories();
-
- // resolve plugin version as necessary
- if (plugin.getVersion() == null) {
- PluginVersionRequest versionRequest = new DefaultPluginVersionRequest(plugin, session, repositories);
- try {
- plugin.setVersion(pluginVersionResolver.resolve(versionRequest).getVersion());
- } catch (PluginVersionResolutionException e) {
- throw new PluginManagerException(plugin, e.getMessage(), e);
- }
- }
-
- // resolve plugin artifacts
- List artifacts;
- PluginArtifactsCache.Key cacheKey = pluginArtifactsCache.createKey(plugin, null, repositories, session);
- PluginArtifactsCache.CacheRecord recordArtifacts;
- try {
- recordArtifacts = pluginArtifactsCache.get(cacheKey);
- } catch (PluginResolutionException e) {
- throw new PluginManagerException(plugin, e.getMessage(), e);
- }
- if (recordArtifacts != null) {
- artifacts = recordArtifacts.getArtifacts();
- } else {
- try {
- artifacts = resolveExtensionArtifacts(plugin, repositories, session);
- recordArtifacts = pluginArtifactsCache.put(cacheKey, artifacts);
- } catch (PluginResolutionException e) {
- pluginArtifactsCache.put(cacheKey, e);
- pluginArtifactsCache.register(project, cacheKey, recordArtifacts);
- throw new PluginManagerException(plugin, e.getMessage(), e);
- }
- }
- pluginArtifactsCache.register(project, cacheKey, recordArtifacts);
-
- // create and cache extensions realms
- final ExtensionRealmCache.Key extensionKey = extensionRealmCache.createKey(artifacts);
- extensionRecord = extensionRealmCache.get(extensionKey);
- if (extensionRecord == null) {
- ClassRealm extensionRealm = classRealmManager.createExtensionRealm(plugin, toAetherArtifacts(artifacts));
-
- // TODO figure out how to use the same PluginDescriptor when running mojos
-
- PluginDescriptor pluginDescriptor = null;
- if (plugin.isExtensions() && !artifacts.isEmpty()) {
- // ignore plugin descriptor parsing errors at this point
- // these errors will reported during calculation of project build execution plan
- try {
- pluginDescriptor = extractPluginDescriptor(artifacts.get(0), plugin);
- } catch (PluginDescriptorParsingException | InvalidPluginDescriptorException e) {
- // ignore, see above
- }
- }
-
- discoverPluginComponents(extensionRealm, plugin, pluginDescriptor);
-
- ExtensionDescriptor extensionDescriptor = null;
- Artifact extensionArtifact = artifacts.get(0);
- try {
- extensionDescriptor = extensionDescriptorBuilder.build(extensionArtifact.getFile());
- } catch (IOException e) {
- String message = "Invalid extension descriptor for " + plugin.getId() + ": " + e.getMessage();
- if (logger.isDebugEnabled()) {
- logger.error(message, e);
- } else {
- logger.error(message);
- }
- }
- extensionRecord = extensionRealmCache.put(extensionKey, extensionRealm, extensionDescriptor, artifacts);
- }
- extensionRealmCache.register(project, extensionKey, extensionRecord);
- pluginRealms.put(pluginKey, extensionRecord);
-
- return extensionRecord;
- }
-
- private List resolveExtensionArtifacts(
- Plugin extensionPlugin, List repositories, RepositorySystemSession session)
- throws PluginResolutionException {
- DependencyNode root = pluginDependenciesResolver.resolve(extensionPlugin, null, null, repositories, session);
- PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
- root.accept(nlg);
- return toMavenArtifacts(root, nlg);
- }
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/ValidatingConfigurationListener.java b/daemon/src/main/java/org/mvndaemon/mvnd/plugin/ValidatingConfigurationListener.java
deleted file mode 100644
index a7aa258b8..000000000
--- a/daemon/src/main/java/org/mvndaemon/mvnd/plugin/ValidatingConfigurationListener.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.mvndaemon.mvnd.plugin;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.maven.plugin.descriptor.MojoDescriptor;
-import org.apache.maven.plugin.descriptor.Parameter;
-import org.codehaus.plexus.component.configurator.ConfigurationListener;
-
-/**
- * A configuration listener to help validate the plugin configuration. For instance, check for required but missing
- * parameters.
- *
- * @author Benjamin Bentmann
- */
-class ValidatingConfigurationListener implements ConfigurationListener {
-
- private final Object mojo;
-
- private final ConfigurationListener delegate;
-
- private final Map missingParameters;
-
- ValidatingConfigurationListener(Object mojo, MojoDescriptor mojoDescriptor, ConfigurationListener delegate) {
- this.mojo = mojo;
- this.delegate = delegate;
- this.missingParameters = new HashMap<>();
-
- if (mojoDescriptor.getParameters() != null) {
- for (Parameter param : mojoDescriptor.getParameters()) {
- if (param.isRequired()) {
- missingParameters.put(param.getName(), param);
- }
- }
- }
- }
-
- public Collection getMissingParameters() {
- return missingParameters.values();
- }
-
- public void notifyFieldChangeUsingSetter(String fieldName, Object value, Object target) {
- delegate.notifyFieldChangeUsingSetter(fieldName, value, target);
-
- if (mojo == target) {
- notify(fieldName, value);
- }
- }
-
- public void notifyFieldChangeUsingReflection(String fieldName, Object value, Object target) {
- delegate.notifyFieldChangeUsingReflection(fieldName, value, target);
-
- if (mojo == target) {
- notify(fieldName, value);
- }
- }
-
- private void notify(String fieldName, Object value) {
- if (value != null) {
- missingParameters.remove(fieldName);
- }
- }
-}
diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/syncontext/DaemonNamedLockFactoryAdapterFactoryImpl.java b/daemon/src/main/java/org/mvndaemon/mvnd/syncontext/DaemonNamedLockFactoryAdapterFactoryImpl.java
new file mode 100644
index 000000000..64ec7e0fe
--- /dev/null
+++ b/daemon/src/main/java/org/mvndaemon/mvnd/syncontext/DaemonNamedLockFactoryAdapterFactoryImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.mvndaemon.mvnd.syncontext;
+
+import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import org.eclipse.aether.impl.RepositorySystemLifecycle;
+import org.eclipse.aether.internal.impl.synccontext.named.NameMapper;
+import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl;
+import org.eclipse.aether.internal.impl.synccontext.named.providers.FileGAVNameMapperProvider;
+import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.named.providers.FileLockNamedLockFactory;
+import org.eclipse.sisu.Priority;
+
+/**
+ * Mvnd named lock factory implementation: it differs from
+ * {@link org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapterFactoryImpl} only by default values.
+ */
+@Singleton
+@Named
+@Priority(10)
+public final class DaemonNamedLockFactoryAdapterFactoryImpl extends NamedLockFactoryAdapterFactoryImpl {
+ @Inject
+ public DaemonNamedLockFactoryAdapterFactoryImpl(
+ final Map factories,
+ final Map nameMappers,
+ final RepositorySystemLifecycle lifecycle) {
+ super(factories, FileLockNamedLockFactory.NAME, nameMappers, FileGAVNameMapperProvider.NAME, lifecycle);
+ }
+}
diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/SingleModuleNativeIT.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/SingleModuleNativeIT.java
index 66a8b9d6a..ea4e71cf3 100644
--- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/SingleModuleNativeIT.java
+++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/SingleModuleNativeIT.java
@@ -90,7 +90,9 @@ protected void assertJVM(TestClientOutput o, Properties props) {
}
String mojoStartedLogMessage(Properties props, String pluginArtifactId, String mojo, String executionId) {
- return "\\Q--- " + pluginArtifactId + ":" + props.getProperty(pluginArtifactId + ".version") + ":" + mojo + " ("
+ return "\\Q--- "
+ + pluginArtifactId.replace("maven-", "").replace("-plugin", "")
+ + ":" + props.getProperty(pluginArtifactId + ".version") + ":" + mojo + " ("
+ executionId + ") @ single-module ---\\E";
}
}
diff --git a/integration-tests/src/test/projects/invoker/pom.xml b/integration-tests/src/test/projects/invoker/pom.xml
index f65cc1a14..f118dc94f 100644
--- a/integration-tests/src/test/projects/invoker/pom.xml
+++ b/integration-tests/src/test/projects/invoker/pom.xml
@@ -89,6 +89,7 @@
${project.build.directory}/it
${project.build.directory}/local-repo
verify
+ ${settingsFile}
@@ -103,4 +104,18 @@
+
+
+
+ settings
+
+
+ ${project.basedir}/../settings.xml
+
+
+
+ ${project.basedir}/../settings.xml
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8e4e01238..564665030 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,9 +84,10 @@
3.21.0
5.9.1
1.2.11
- 4.0.0-alpha-2
- 1.8.2
- 1.7.35
+ 4.0.0-alpha-3
+
+ 1.9.2
+ 1.7.36
0.3.5