All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.plugin.internal.DefaultMavenPluginManager Maven / Gradle / Ivy

There is a newer version: 4.0.0-alpha-13
Show newest version
package org.apache.maven.plugin.internal;

/*
 * 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.
 */

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.monitor.logging.DefaultLog;
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.MavenPluginValidator;
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.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.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
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.Logger;
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 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.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;

/**
 * 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
 */
@Component( role = MavenPluginManager.class )
public class DefaultMavenPluginManager
    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 = DefaultMavenPluginManager.class.getName() + "/extensionsRealms"; @Requirement private Logger logger; @Requirement private LoggerManager loggerManager; @Requirement private PlexusContainer container; @Requirement private ClassRealmManager classRealmManager; @Requirement private PluginDescriptorCache pluginDescriptorCache; @Requirement private PluginRealmCache pluginRealmCache; @Requirement private PluginDependenciesResolver pluginDependenciesResolver; @Requirement private RuntimeInformation runtimeInformation; @Requirement private ExtensionRealmCache extensionRealmCache; @Requirement private PluginVersionResolver pluginVersionResolver; @Requirement private PluginArtifactsCache pluginArtifactsCache; private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder(); private PluginDescriptorBuilder builder = new PluginDescriptorBuilder(); public synchronized 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 ); if ( pluginDescriptor == null ) { org.eclipse.aether.artifact.Artifact artifact = pluginDependenciesResolver.resolve( plugin, repositories, session ); Artifact pluginArtifact = RepositoryUtils.toArtifact( artifact ); pluginDescriptor = extractPluginDescriptor( pluginArtifact, plugin ); pluginDescriptor.setRequiredMavenVersion( artifact.getProperty( "requiredMavenVersion", null ) ); pluginDescriptorCache.put( cacheKey, pluginDescriptor ); } 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 ); } MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact ); validator.validate( pluginDescriptor ); if ( validator.hasErrors() ) { throw new InvalidPluginDescriptorException( "Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", validator.getErrors() ); } pluginDescriptor.setPluginArtifact( pluginArtifact ); return pluginDescriptor; } 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 synchronized 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 ); if ( cacheRecord != null ) { pluginDescriptor.setClassRealm( cacheRecord.getRealm() ); pluginDescriptor.setArtifacts( new ArrayList<>( cacheRecord.getArtifacts() ) ); for ( ComponentDescriptor componentDescriptor : pluginDescriptor.getComponents() ) { componentDescriptor.setRealm( cacheRecord.getRealm() ); } } else { createPluginRealm( pluginDescriptor, session, parent, foreignImports, filter ); cacheRecord = pluginRealmCache.put( cacheKey, pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() ); } 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 ); 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 ) { Logger mojoLogger = loggerManager.getLoggerForComponent( mojoDescriptor.getImplementation() ); ( (Mojo) mojo ).setLog( new DefaultLog( 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 ); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy