MNG-4041: maven core returns stale project state during extended use. this is a patch which provides intelligent caching and yields a very substantial performance improvement.

Submitted by: Igor Fedorenko



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@782014 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jason van Zyl 2009-06-05 13:49:25 +00:00
parent 5787b70567
commit 09f970f178
26 changed files with 433 additions and 613 deletions

View File

@ -171,7 +171,7 @@ public class DefaultMaven
return result; return result;
} }
protected Map<String,MavenProject> getProjects( MavenExecutionRequest request ) public Map<String,MavenProject> getProjects( MavenExecutionRequest request )
throws MavenExecutionException, ProjectBuildingException throws MavenExecutionException, ProjectBuildingException
{ {
// We have no POM file. // We have no POM file.

View File

@ -54,7 +54,7 @@ public class DefaultProjectDependenciesResolver
ArtifactFilter filter; ArtifactFilter filter;
if ( exclusions != null ) if ( ! exclusions.isEmpty() )
{ {
filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{ new ExcludesArtifactFilter( exclusions ), scopeFilter } ) ); filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{ new ExcludesArtifactFilter( exclusions ), scopeFilter } ) );
} }

View File

@ -1,25 +0,0 @@
package org.apache.maven.execution;
import org.apache.maven.artifact.versioning.ArtifactVersion;
public class ApplicationInformation
{
private ArtifactVersion version;
private String builtOn;
public ApplicationInformation( ArtifactVersion version, String builtOn )
{
this.version = version;
this.builtOn = builtOn;
}
public ArtifactVersion getVersion()
{
return version;
}
public String getBuiltOn()
{
return builtOn;
}
}

View File

@ -1,109 +0,0 @@
package org.apache.maven.execution;
/*
* 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 java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.util.IOUtil;
/**
* Describes runtime information about the application.
*
* @author Jason van Zyl
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
@Component(role = RuntimeInformation.class)
public class DefaultRuntimeInformation
implements RuntimeInformation, Initializable
{
private ApplicationInformation applicationInformation;
public ApplicationInformation getApplicationInformation()
{
return applicationInformation;
}
/** @deprecated Use getApplicationInformation() */
public ArtifactVersion getApplicationVersion()
{
return applicationInformation.getVersion();
}
public void initialize()
throws InitializationException
{
applicationInformation = getVersion( getClass().getClassLoader(), "org.apache.maven", "maven-core" );
}
public static ApplicationInformation getVersion( ClassLoader loader, String groupId, String artifactId )
{
String MAVEN_PROPERTIES = "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties";
String version = "unknown";
String builtOn = "unknown";
InputStream resourceAsStream = null;
try
{
Properties properties = new Properties();
resourceAsStream = loader.getResourceAsStream( MAVEN_PROPERTIES );
if ( resourceAsStream == null )
{
return new ApplicationInformation( new DefaultArtifactVersion( "3.0" ), builtOn );
}
properties.load( resourceAsStream );
String property = properties.getProperty( "version" );
if ( property != null )
{
version = property;
}
property = properties.getProperty( "builtOn" );
if ( property != null )
{
builtOn = property;
}
return new ApplicationInformation( new DefaultArtifactVersion( version ), builtOn );
}
catch ( IOException e )
{
return new ApplicationInformation( new DefaultArtifactVersion( version ), builtOn );
}
finally
{
IOUtil.close( resourceAsStream );
}
}
}

View File

@ -1,38 +0,0 @@
package org.apache.maven.execution;
import org.apache.maven.artifact.versioning.ArtifactVersion;
/*
* 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.
*/
/**
* Describes runtime information about the application.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface RuntimeInformation
{
ApplicationInformation getApplicationInformation();
/** @deprecated Use getApplicationInformation() */
//!!BC Used by the Eclipse Plugin
ArtifactVersion getApplicationVersion();
}

View File

@ -47,6 +47,7 @@ import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException; import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginManager; import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
@ -221,7 +222,7 @@ public class DefaultLifecycleExecutor
// 4. Bind those mojos found in the lifecycle mapping for the packaging to the lifecycle // 4. Bind those mojos found in the lifecycle mapping for the packaging to the lifecycle
// 5. Bind mojos specified in the project itself to the lifecycle // 5. Bind mojos specified in the project itself to the lifecycle
public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, PluginManagerException
{ {
MavenProject project = session.getCurrentProject(); MavenProject project = session.getCurrentProject();
@ -394,7 +395,13 @@ public class DefaultLifecycleExecutor
// org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
// //
MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor(
mojoExecution.getGroupId(), mojoExecution.getArtifactId(), mojoExecution.getVersion(), mojoExecution.getGoal(), session.getLocalRepository(), project.getRemoteArtifactRepositories() ); mojoExecution.getGroupId(), mojoExecution.getArtifactId(), mojoExecution.getVersion(), mojoExecution.getGoal(), session.getLocalRepository(), project.getPluginArtifactRepositories() );
PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
if ( pluginDescriptor.getPlugin().isExtensions() )
{
pluginDescriptor.setClassRealm( pluginManager.getPluginRealm( session, pluginDescriptor ) );
}
requiredDependencyResolutionScope = calculateRequiredDependencyResolutionScope( requiredDependencyResolutionScope, mojoDescriptor.isDependencyResolutionRequired() ); requiredDependencyResolutionScope = calculateRequiredDependencyResolutionScope( requiredDependencyResolutionScope, mojoDescriptor.isDependencyResolutionRequired() );

View File

@ -30,6 +30,7 @@ import org.apache.maven.plugin.CycleDetectedInPluginGraphException;
import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MojoNotFoundException; import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.PluginResolutionException;
@ -50,7 +51,7 @@ public interface LifecycleExecutor
* @throws LifecycleExecutionException * @throws LifecycleExecutionException
*/ */
MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException; throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, PluginManagerException;
// For a given project packaging find all the plugins that are bound to any registered // For a given project packaging find all the plugins that are bound to any registered
// lifecycles. The project builder needs to now what default plugin information needs to be // lifecycles. The project builder needs to now what default plugin information needs to be

View File

@ -1,29 +0,0 @@
package org.apache.maven.plugin;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.annotations.Component;
@Component(role=PluginClassLoaderCache.class)
public class DefaultPluginClassLoaderCache
implements PluginClassLoaderCache
{
private Map<String,ClassRealm> pluginClassLoaders = new HashMap<String,ClassRealm>();
public void put( String key, ClassRealm pluginClassLoader )
{
pluginClassLoaders.put( key, pluginClassLoader );
}
public ClassRealm get( String key )
{
return pluginClassLoaders.get( key );
}
public int size()
{
return pluginClassLoaders.size();
}
}

View File

@ -15,21 +15,20 @@ package org.apache.maven.plugin;
* the License. * the License.
*/ */
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.apache.maven.ArtifactFilterManager; import org.apache.maven.ArtifactFilterManager;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
@ -52,8 +51,11 @@ import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
import org.apache.maven.project.DuplicateArtifactAttachmentException; import org.apache.maven.project.DuplicateArtifactAttachmentException;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.MutablePlexusContainer;
import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException; import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
@ -61,23 +63,18 @@ import org.codehaus.plexus.component.configurator.ComponentConfigurationExceptio
import org.codehaus.plexus.component.configurator.ComponentConfigurator; import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.ConfigurationListener; import org.codehaus.plexus.component.configurator.ConfigurationListener;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.discovery.ComponentDiscoverer;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
import org.codehaus.plexus.component.repository.ComponentDescriptor; import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException; import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration; import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.PlexusConfigurationException; import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextMapAdapter;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.InterpolationFilterReader; import org.codehaus.plexus.util.InterpolationFilterReader;
import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.XmlStreamReader;
import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3Dom;
// TODO: get plugin groups // TODO: get plugin groups
@ -88,12 +85,12 @@ import org.codehaus.plexus.util.xml.Xpp3Dom;
@Component(role = PluginManager.class) @Component(role = PluginManager.class)
public class DefaultPluginManager public class DefaultPluginManager
implements PluginManager, ComponentDiscoverer, ComponentDiscoveryListener implements PluginManager
{ {
@Requirement @Requirement
private Logger logger; private Logger logger;
@Requirement @Requirement(role=PlexusContainer.class)
protected PlexusContainer container; protected PlexusContainer container;
@Requirement @Requirement
@ -106,19 +103,7 @@ public class DefaultPluginManager
private ResolutionErrorHandler resolutionErrorHandler; private ResolutionErrorHandler resolutionErrorHandler;
@Requirement @Requirement
private PluginClassLoaderCache pluginClassLoaderCache; private PluginCache pluginCache;
private Map<String, PluginDescriptor> pluginDescriptors;
public DefaultPluginManager()
{
pluginDescriptors = new HashMap<String, PluginDescriptor>();
}
private String pluginKey( Plugin plugin )
{
return plugin.getGroupId() + ":" + plugin.getArtifactId() + ":" + plugin.getVersion();
}
/** /**
* *
@ -133,24 +118,33 @@ public class DefaultPluginManager
* happen but if someone has made a descriptor by hand it's possible. * happen but if someone has made a descriptor by hand it's possible.
* @throws CycleDetectedInComponentGraphException A cycle has been detected in the component graph for a plugin that has been dynamically loaded. * @throws CycleDetectedInComponentGraphException A cycle has been detected in the component graph for a plugin that has been dynamically loaded.
*/ */
public PluginDescriptor loadPlugin( Plugin plugin, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) public synchronized PluginDescriptor loadPlugin( Plugin plugin, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, InvalidPluginDescriptorException throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, InvalidPluginDescriptorException
{ {
PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin ); // PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin );
// There are cases where plugins are discovered but not actually populated. These are edge cases where you are working in the IDE on // There are cases where plugins are discovered but not actually populated. These are edge cases where you are working in the IDE on
// Maven itself so this speaks to a problem we have with the system not starting entirely clean. // Maven itself so this speaks to a problem we have with the system not starting entirely clean.
if ( pluginDescriptor != null && pluginDescriptor.getClassRealm() != null ) // if ( pluginDescriptor != null && pluginDescriptor.getClassRealm() != null )
// {
// return pluginDescriptor;
// }
PluginDescriptor pluginDescriptor = pluginCache.getPluginDescriptor( plugin, localRepository, remoteRepositories );
if ( pluginDescriptor != null )
{ {
return pluginDescriptor; return pluginDescriptor;
} }
Artifact pluginArtifact = repositorySystem.createPluginArtifact( plugin ); Artifact pluginArtifact = repositorySystem.createPluginArtifact( plugin );
ArtifactResolutionRequest request = new ArtifactResolutionRequest() ArtifactResolutionRequest request = new ArtifactResolutionRequest()
.setArtifact( pluginArtifact ) .setArtifact( pluginArtifact )
.setLocalRepository( localRepository ) .setLocalRepository( localRepository )
.setRemoteRepostories( remoteRepositories ); .setRemoteRepostories( remoteRepositories )
.setResolveTransitively( false );
ArtifactResolutionResult result = repositorySystem.resolve( request ); ArtifactResolutionResult result = repositorySystem.resolve( request );
@ -163,80 +157,98 @@ public class DefaultPluginManager
throw new PluginResolutionException( plugin, e ); throw new PluginResolutionException( plugin, e );
} }
ClassRealm pluginRealm = pluginClassLoaderCache.get( constructPluginKey( plugin ) );
if ( pluginRealm != null )
{
return getPluginDescriptor( plugin );
}
pluginRealm = container.createChildRealm( pluginKey( plugin ) );
Set<Artifact> pluginArtifacts;
try try
{ {
pluginArtifacts = getPluginArtifacts( pluginArtifact, plugin, localRepository, remoteRepositories ); if ( pluginArtifact.getFile().isFile() )
}
catch ( ArtifactNotFoundException e )
{
throw new PluginNotFoundException( plugin, e );
}
catch ( ArtifactResolutionException e )
{
throw new PluginResolutionException( plugin, e );
}
for ( Artifact a : pluginArtifacts )
{ {
JarFile pluginJar = new JarFile( pluginArtifact.getFile() );
try try
{ {
pluginRealm.addURL( a.getFile().toURI().toURL() ); ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getComponentDescriptorLocation() );
}
catch ( MalformedURLException e ) if ( pluginDescriptorEntry != null )
{ {
// Not going to happen InputStream is = pluginJar.getInputStream( pluginDescriptorEntry );
pluginDescriptor = parsebuildPluginDescriptor( is );
}
}
finally
{
pluginJar.close();
}
}
else
{
File pluginXml = new File( pluginArtifact.getFile(), getComponentDescriptorLocation() );
if ( pluginXml.canRead() )
{
InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) );
try
{
pluginDescriptor = parsebuildPluginDescriptor( is );
}
finally
{
IOUtil.close( is );
}
} }
} }
String pluginKey = constructPluginKey( plugin ); String pluginKey = constructPluginKey( plugin );
if ( pluginDescriptor == null )
{
throw new InvalidPluginDescriptorException( "Invalid or missing Plugin Descriptor for " + pluginKey );
}
// Check the internal consistent of a plugin descriptor when it is discovered. Most of the time the plugin descriptor is generated // Check the internal consistent of a plugin descriptor when it is discovered. Most of the time the plugin descriptor is generated
// by the maven-plugin-plugin, but if you happened to have created one by hand and it's incorrect this validator will report // by the maven-plugin-plugin, but if you happened to have created one by hand and it's incorrect this validator will report
// the problem to the user. // the problem to the user.
// //
MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact ); MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact );
try validator.validate( pluginDescriptor );
{
container.discoverComponents( pluginRealm, validator );
}
catch ( PlexusConfigurationException e )
{
throw new PluginDescriptorParsingException( plugin, e );
}
catch ( CycleDetectedInComponentGraphException e )
{
throw new CycleDetectedInPluginGraphException( plugin, e );
}
if ( validator.hasErrors() ) if ( validator.hasErrors() )
{ {
throw new InvalidPluginDescriptorException( "Invalid Plugin Descriptor for " + pluginKey, validator.getErrors() ); throw new InvalidPluginDescriptorException( "Invalid Plugin Descriptor for " + pluginKey, validator.getErrors() );
} }
pluginClassLoaderCache.put( pluginKey, pluginRealm ); pluginDescriptor.setPlugin( plugin );
pluginDescriptor.setPluginArtifact( pluginArtifact );
pluginDescriptor = getPluginDescriptor( plugin ); pluginCache.putPluginDescriptor( plugin, localRepository, remoteRepositories, pluginDescriptor );
pluginDescriptor.setArtifacts( new ArrayList<Artifact>( pluginArtifacts ) );
return pluginDescriptor; return pluginDescriptor;
}
catch ( IOException e )
{
throw new PluginDescriptorParsingException( plugin, e );
}
catch ( PlexusConfigurationException e )
{
throw new PluginDescriptorParsingException( plugin, e );
}
}
private PluginDescriptor parsebuildPluginDescriptor( InputStream is )
throws IOException, PlexusConfigurationException
{
PluginDescriptor pluginDescriptor;
XmlStreamReader reader = ReaderFactory.newXmlReader( is );
InterpolationFilterReader interpolationFilterReader = new InterpolationFilterReader( new BufferedReader( reader ), container.getContext().getContextData() );
pluginDescriptor = builder.build( interpolationFilterReader );
return pluginDescriptor;
} }
// TODO: Turn this into a component so it can be tested. // TODO: Turn this into a component so it can be tested.
// //
Set<Artifact> getPluginArtifacts( Artifact pluginArtifact, Plugin pluginAsSpecifiedInPom, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) List<Artifact> getPluginArtifacts( Artifact pluginArtifact, Plugin pluginAsSpecifiedInPom, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws ArtifactNotFoundException, ArtifactResolutionException throws ArtifactNotFoundException, ArtifactResolutionException
{ {
AndArtifactFilter filter = new AndArtifactFilter(); AndArtifactFilter filter = new AndArtifactFilter();
@ -284,7 +296,7 @@ public class DefaultPluginManager
logger.debug( "Using the following artifacts for classpath of: " + pluginArtifact.getId() + ":\n\n" + result.getArtifacts().toString().replace( ',', '\n' ) ); logger.debug( "Using the following artifacts for classpath of: " + pluginArtifact.getId() + ":\n\n" + result.getArtifacts().toString().replace( ',', '\n' ) );
return result.getArtifacts(); return new ArrayList<Artifact>( result.getArtifacts() );
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -292,7 +304,7 @@ public class DefaultPluginManager
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
public void executeMojo( MavenSession session, MojoExecution mojoExecution ) public void executeMojo( MavenSession session, MojoExecution mojoExecution )
throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginExecutionException throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException
{ {
MavenProject project = session.getCurrentProject(); MavenProject project = session.getCurrentProject();
@ -308,8 +320,7 @@ public class DefaultPluginManager
goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}"; goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}";
} }
// by this time, the pluginDescriptor has had the correct realm setup from getConfiguredMojo(..) ClassRealm pluginRealm = getPluginRealm( session, mojoDescriptor.getPluginDescriptor() );
ClassRealm pluginRealm = pluginClassLoaderCache.get( constructPluginKey( mojoDescriptor.getPluginDescriptor() ) );
ClassRealm oldLookupRealm = container.getLookupRealm(); ClassRealm oldLookupRealm = container.getLookupRealm();
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
@ -358,6 +369,121 @@ public class DefaultPluginManager
} }
} }
/**
* TODO pluginDescriptor classRealm and artifacts are set as a side effect of this
* call, which is not nice.
*/
public synchronized ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) throws PluginManagerException
{
ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
if ( pluginRealm != null )
{
return pluginRealm;
}
Plugin plugin = pluginDescriptor.getPlugin();
ArtifactRepository localRepository = session.getLocalRepository();
List<ArtifactRepository> remoteRepositories = session.getCurrentProject().getPluginArtifactRepositories();
PluginCache.CacheRecord cacheRecord = pluginCache.get( plugin, localRepository, remoteRepositories );
if ( cacheRecord != null )
{
pluginDescriptor.setClassRealm( cacheRecord.realm );
pluginDescriptor.setArtifacts( new ArrayList<Artifact>( cacheRecord.artifacts ) );
return pluginRealm;
}
pluginRealm = createPluginRealm( plugin );
Artifact pluginArtifact = pluginDescriptor.getPluginArtifact();
List<Artifact> pluginArtifacts;
try
{
pluginArtifacts = getPluginArtifacts( pluginArtifact, plugin, localRepository, remoteRepositories );
}
catch ( ArtifactNotFoundException e )
{
throw new IllegalStateException( e ); // XXX
}
catch ( ArtifactResolutionException e )
{
throw new IllegalStateException( e ); // XXX
}
for ( Artifact a : pluginArtifacts )
{
try
{
pluginRealm.addURL( a.getFile().toURI().toURL() );
}
catch ( MalformedURLException e )
{
// Not going to happen
}
}
pluginDescriptor.setClassRealm( pluginRealm );
pluginDescriptor.setArtifacts( pluginArtifacts );
try
{
for ( ComponentDescriptor componentDescriptor : pluginDescriptor.getComponents() )
{
componentDescriptor.setRealm( pluginRealm );
container.addComponentDescriptor( componentDescriptor );
}
container.discoverComponents( pluginRealm );
}
catch ( PlexusConfigurationException e )
{
throw new PluginManagerException( plugin, e.getMessage(), e );
}
catch ( CycleDetectedInComponentGraphException e )
{
throw new PluginManagerException( plugin, e.getMessage(), e );
}
pluginCache.put( plugin, localRepository, remoteRepositories, pluginRealm, pluginArtifacts );
return pluginRealm;
}
/**
* Creates ClassRealm with unique id for the given plugin
*/
private ClassRealm createPluginRealm( Plugin plugin )
throws PluginManagerException
{
ClassWorld world = ((MutablePlexusContainer) container).getClassWorld();
String baseRealmId = constructPluginKey( plugin );
String realmId = baseRealmId;
synchronized ( world )
{
for ( int i = 0; i < 100; i++ )
{
try
{
ClassRealm pluginRealm = world.newRealm( realmId );
pluginRealm.setParentRealm( container.getContainerRealm() );
return pluginRealm;
}
catch ( DuplicateRealmException e )
{
realmId = baseRealmId + "-" + i;
}
}
}
throw new PluginManagerException( plugin, "Could not create ClassRealm", (Throwable) null );
}
private Mojo getConfiguredMojo( MavenSession session, MavenProject project, MojoExecution mojoExecution, ClassRealm pluginRealm ) private Mojo getConfiguredMojo( MavenSession session, MavenProject project, MojoExecution mojoExecution, ClassRealm pluginRealm )
throws PluginConfigurationException, PluginManagerException throws PluginConfigurationException, PluginManagerException
{ {
@ -368,11 +494,14 @@ public class DefaultPluginManager
// We are forcing the use of the plugin realm for all lookups that might occur during // 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 // 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. // lookups that occur in contextualize calls in line with the right realm.
container.setLookupRealm( pluginRealm ); ClassRealm oldLookupRealm = container.setLookupRealm( pluginRealm );
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader( pluginRealm ); Thread.currentThread().setContextClassLoader( pluginRealm );
container.setLookupRealm( pluginRealm );
try
{
Mojo mojo; Mojo mojo;
try try
@ -419,10 +548,15 @@ public class DefaultPluginManager
populatePluginFields( mojo, mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator ); populatePluginFields( mojo, mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator );
Thread.currentThread().setContextClassLoader( oldClassLoader );
return mojo; return mojo;
} }
finally
{
Thread.currentThread().setContextClassLoader( oldClassLoader );
container.setLookupRealm( oldLookupRealm );
}
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Mojo Parameter Handling // Mojo Parameter Handling
@ -553,118 +687,10 @@ public class DefaultPluginManager
return "META-INF/maven/plugin.xml"; return "META-INF/maven/plugin.xml";
} }
public ComponentSetDescriptor createComponentDescriptors( Reader componentDescriptorConfiguration, String source )
throws PlexusConfigurationException
{
return builder.build( componentDescriptorConfiguration, source );
}
public List<ComponentSetDescriptor> findComponents( Context context, ClassRealm realm )
throws PlexusConfigurationException
{
List<ComponentSetDescriptor> componentSetDescriptors = new ArrayList<ComponentSetDescriptor>();
Enumeration<URL> resources;
try
{
// We don't always want to scan parent realms. For plexus
// testcase, most components are in the root classloader so that needs to be scanned,
// but for child realms, we don't.
if ( realm.getParentRealm() != null )
{
resources = realm.findRealmResources( getComponentDescriptorLocation() );
}
else
{
resources = realm.findResources( getComponentDescriptorLocation() );
}
}
catch ( IOException e )
{
throw new PlexusConfigurationException( "Unable to retrieve resources for: " + getComponentDescriptorLocation() + " in class realm: " + realm.getId() );
}
for ( URL url : Collections.list( resources ) )
{
Reader reader = null;
try
{
URLConnection conn = url.openConnection();
conn.setUseCaches( false );
conn.connect();
reader = ReaderFactory.newXmlReader( conn.getInputStream() );
InterpolationFilterReader interpolationFilterReader = new InterpolationFilterReader( reader, new ContextMapAdapter( context ) );
ComponentSetDescriptor componentSetDescriptor = createComponentDescriptors( interpolationFilterReader, url.toString() );
if ( componentSetDescriptor.getComponents() != null )
{
for ( ComponentDescriptor<?> cd : componentSetDescriptor.getComponents() )
{
cd.setComponentSetDescriptor( componentSetDescriptor );
cd.setRealm( realm );
}
}
componentSetDescriptors.add( componentSetDescriptor );
}
catch ( IOException ex )
{
throw new PlexusConfigurationException( "Error reading configuration " + url, ex );
}
finally
{
IOUtil.close( reader );
}
}
return componentSetDescriptors;
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Component Discovery Listener // Component Discovery Listener
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private Set pluginsInProcess = new HashSet();
public void componentDiscovered( ComponentDiscoveryEvent event )
{
ComponentSetDescriptor componentSetDescriptor = event.getComponentSetDescriptor();
if ( componentSetDescriptor instanceof PluginDescriptor )
{
PluginDescriptor pluginDescriptor = (PluginDescriptor) componentSetDescriptor;
MavenPluginValidator validator = (MavenPluginValidator) event.getData();
validator.validate( pluginDescriptor );
if ( validator.hasErrors() )
{
return;
}
String key = constructPluginKey( pluginDescriptor );
if ( !pluginsInProcess.contains( key ) )
{
pluginsInProcess.add( key );
pluginDescriptors.put( key, pluginDescriptor );
}
}
}
public PluginDescriptor getPluginDescriptor( Plugin plugin )
{
return pluginDescriptors.get( constructPluginKey( plugin ) );
}
public String constructPluginKey( Plugin plugin ) public String constructPluginKey( Plugin plugin )
{ {
String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() ); String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() );

View File

@ -32,6 +32,11 @@ public class InvalidPluginDescriptorException
this.errors = errors; this.errors = errors;
} }
public InvalidPluginDescriptorException( String message )
{
super( message );
}
private static String toMessage( String message, List<String> errors ) private static String toMessage( String message, List<String> errors )
{ {
StringBuilder buffer = new StringBuilder( 256 ); StringBuilder buffer = new StringBuilder( 256 );

View File

@ -20,11 +20,6 @@ package org.apache.maven.plugin;
*/ */
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
/** /**
* @author Jason van Zyl * @author Jason van Zyl
@ -34,7 +29,7 @@ public class PluginDescriptorParsingException
{ {
private Plugin plugin; private Plugin plugin;
public PluginDescriptorParsingException( Plugin plugin, PlexusConfigurationException e ) public PluginDescriptorParsingException( Plugin plugin, Exception e )
{ {
super( e ); super( e );
this.plugin = plugin; this.plugin = plugin;

View File

@ -22,14 +22,12 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.codehaus.plexus.component.discovery.ComponentDiscoverer; import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
/** /**
* @author Jason van Zyl * @author Jason van Zyl
*/ */
public interface PluginManager public interface PluginManager
extends ComponentDiscoverer, ComponentDiscoveryListener
{ {
// - find the plugin [extension point: any client may wish to do whatever they choose] // - find the plugin [extension point: any client may wish to do whatever they choose]
// - load the plugin into a classloader [extension point: we want to take them from a repository, some may take from disk or whatever] // - load the plugin into a classloader [extension point: we want to take them from a repository, some may take from disk or whatever]
@ -41,16 +39,22 @@ public interface PluginManager
// plugin resolution exception // plugin resolution exception
// plugin configuration can't be parsed -- and this may be a result of client insertion of configuration // plugin configuration can't be parsed -- and this may be a result of client insertion of configuration
// plugin component deps have a cycle -- this should be prevented for the most part but client code may inject an override component which itself has a cycle // plugin component deps have a cycle -- this should be prevented for the most part but client code may inject an override component which itself has a cycle
// igorf: Way too many declared exceptions!
PluginDescriptor loadPlugin( Plugin plugin, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) PluginDescriptor loadPlugin( Plugin plugin, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, InvalidPluginDescriptorException; throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, InvalidPluginDescriptorException;
// igorf: Way too many declared exceptions!
MojoDescriptor getMojoDescriptor( String groupId, String artifactId, String version, String goal, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) MojoDescriptor getMojoDescriptor( String groupId, String artifactId, String version, String goal, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, InvalidPluginDescriptorException; throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, InvalidPluginDescriptorException;
// igorf: Way too many declared exceptions!
MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, InvalidPluginDescriptorException; throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, CycleDetectedInPluginGraphException, MojoNotFoundException, InvalidPluginDescriptorException;
// Why do we have a plugin execution exception as well? // Why do we have a plugin execution exception as well?
// igorf: Way too many declared exceptions!
void executeMojo( MavenSession session, MojoExecution execution ) void executeMojo( MavenSession session, MojoExecution execution )
throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginExecutionException; throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginExecutionException, PluginManagerException;
ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor ) throws PluginManagerException;
} }

View File

@ -1,52 +0,0 @@
package org.apache.maven.project;
/*
* 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 java.util.HashMap;
import java.util.Map;
import org.codehaus.plexus.component.annotations.Component;
@Component(role=MavenProjectCache.class)
public class DefaultMavenProjectCache
implements MavenProjectCache
{
private Map<String, MavenProject> projectCache = new HashMap<String, MavenProject>();
public MavenProject get( String key )
{
return projectCache.get( key );
}
public void put( String key, MavenProject project )
{
projectCache.put( key, project );
}
public void clear()
{
projectCache.clear();
}
public int size()
{
return projectCache.size();
}
}

View File

@ -67,9 +67,6 @@ public class DefaultProjectBuilder
@Requirement @Requirement
private ResolutionErrorHandler resolutionErrorHandler; private ResolutionErrorHandler resolutionErrorHandler;
@Requirement
private MavenProjectCache projectCache;
private MavenProject superProject; private MavenProject superProject;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -85,15 +82,6 @@ public class DefaultProjectBuilder
private MavenProject build( File pomFile, boolean localProject, ProjectBuildingRequest configuration ) private MavenProject build( File pomFile, boolean localProject, ProjectBuildingRequest configuration )
throws ProjectBuildingException throws ProjectBuildingException
{ {
String cacheKey = getCacheKey( pomFile, configuration );
MavenProject project = projectCache.get( cacheKey );
if ( project != null )
{
return project;
}
ModelResolver resolver = ModelResolver resolver =
new RepositoryModelResolver( repositorySystem, resolutionErrorHandler, configuration.getLocalRepository(), new RepositoryModelResolver( repositorySystem, resolutionErrorHandler, configuration.getLocalRepository(),
configuration.getRemoteRepositories() ); configuration.getRemoteRepositories() );
@ -119,7 +107,7 @@ public class DefaultProjectBuilder
Model model = result.getEffectiveModel(); Model model = result.getEffectiveModel();
project = fromModelToMavenProject( model, result.getRawModels().get( 1 ).getPomFile(), configuration, model.getPomFile() ); MavenProject project = fromModelToMavenProject( model, result.getRawModels().get( 1 ).getPomFile(), configuration, model.getPomFile() );
project.setOriginalModel( result.getRawModel() ); project.setOriginalModel( result.getRawModel() );
@ -144,19 +132,9 @@ public class DefaultProjectBuilder
project.setFile( pomFile ); project.setFile( pomFile );
project.setActiveProfiles( result.getActiveProfiles( result.getRawModel() ) ); project.setActiveProfiles( result.getActiveProfiles( result.getRawModel() ) );
projectCache.put( cacheKey, project );
return project; return project;
} }
private String getCacheKey( File pomFile, ProjectBuildingRequest configuration )
{
StringBuilder buffer = new StringBuilder( 256 );
buffer.append( pomFile.getAbsolutePath() );
buffer.append( '/' ).append( pomFile.lastModified() );
return buffer.toString();
}
public MavenProject build( Artifact artifact, ProjectBuildingRequest configuration ) public MavenProject build( Artifact artifact, ProjectBuildingRequest configuration )
throws ProjectBuildingException throws ProjectBuildingException
{ {

View File

@ -1,36 +0,0 @@
package org.apache.maven.project;
/*
* 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.
*/
public interface MavenProjectCache
{
MavenProject get( String key );
void put( String key, MavenProject project );
/**
* Clears the cache.
*/
void clear();
int size();
}

View File

@ -38,24 +38,26 @@ public class DefaultMavenMetadataCache
public static class CacheKey public static class CacheKey
{ {
Artifact artifact; private final Artifact artifact;
List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>(); private final List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
private final int hashCode;
CacheKey( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) public CacheKey( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
{ {
this.artifact = ArtifactUtils.copyArtifact( artifact ); this.artifact = ArtifactUtils.copyArtifact( artifact );
this.repositories.add( localRepository ); this.repositories.add( localRepository );
this.repositories.addAll( remoteRepositories ); this.repositories.addAll( remoteRepositories );
int hash = 17;
hash = hash * 31 + artifactHashCode( artifact );
hash = hash * 31 + repositories.hashCode();
this.hashCode = hash;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
int hash = 17; return hashCode;
hash = hash * 31 + artifact.hashCode();
hash = hash * 31 + repositories.hashCode();
return hash;
} }
@Override @Override
@ -73,18 +75,57 @@ public class DefaultMavenMetadataCache
CacheKey other = (CacheKey) o; CacheKey other = (CacheKey) o;
return artifact.equals( other.artifact ) && repositories.equals( other.repositories ); return artifactEquals( artifact, other.artifact ) && repositories.equals( other.repositories );
} }
} }
private static int artifactHashCode( Artifact a )
{
int result = 17;
result = 31 * result + a.getGroupId().hashCode();
result = 31 * result + a.getArtifactId().hashCode();
result = 31 * result + a.getType().hashCode();
if ( a.getVersion() != null )
{
result = 31 * result + a.getVersion().hashCode();
}
result = 31 * result + ( a.getClassifier() != null ? a.getClassifier().hashCode() : 0 );
result = 31 * result + ( a.getScope() != null ? a.getScope().hashCode() : 0 );
result = 31 * result + ( a.getDependencyFilter() != null? a.getDependencyFilter().hashCode() : 0 );
result = 31 * result + ( a.isOptional() ? 1 : 0 );
return result;
}
private static boolean artifactEquals( Artifact a1, Artifact a2 )
{
if ( a1 == a2 )
{
return true;
}
return eq( a1.getGroupId(), a2.getGroupId() )
&& eq( a1.getArtifactId(), a2.getArtifactId() )
&& eq( a1.getType(), a2.getType() )
&& eq( a1.getVersion(), a2.getVersion() )
&& eq( a1.getClassifier(), a2.getClassifier() )
&& eq( a1.getScope(), a2.getScope() )
&& eq( a1.getDependencyFilter(), a2.getDependencyFilter() )
&& a1.isOptional() == a2.isOptional();
}
private static <T> boolean eq( T s1, T s2 )
{
return s1 != null? s1.equals( s2 ): s2 == null;
}
public class CacheRecord public class CacheRecord
{ {
Artifact pomArtifact; private Artifact pomArtifact;
List<Artifact> artifacts; private List<Artifact> artifacts;
List<ArtifactRepository> remoteRepositories; private List<ArtifactRepository> remoteRepositories;
long length; private long length;
long timestamp; private long timestamp;
CacheRecord(Artifact pomArtifact, Set<Artifact> artifacts, List<ArtifactRepository> remoteRepositories) CacheRecord(Artifact pomArtifact, Set<Artifact> artifacts, List<ArtifactRepository> remoteRepositories)
{ {
@ -106,6 +147,21 @@ public class DefaultMavenMetadataCache
} }
} }
public Artifact getArtifact()
{
return pomArtifact;
}
public List<Artifact> getArtifacts()
{
return artifacts;
}
public List<ArtifactRepository> getRemoteRepositories()
{
return remoteRepositories;
}
public boolean isStale() public boolean isStale()
{ {
File pomFile = pomArtifact.getFile(); File pomFile = pomArtifact.getFile();
@ -118,7 +174,7 @@ public class DefaultMavenMetadataCache
} }
} }
private Map<CacheKey, CacheRecord> cache = new HashMap<CacheKey, CacheRecord>(); protected Map<CacheKey, CacheRecord> cache = new HashMap<CacheKey, CacheRecord>();
public ResolutionGroup get( Artifact artifact, ArtifactRepository localRepository, public ResolutionGroup get( Artifact artifact, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories ) List<ArtifactRepository> remoteRepositories )
@ -129,9 +185,9 @@ public class DefaultMavenMetadataCache
if ( cacheRecord != null && !cacheRecord.isStale() ) if ( cacheRecord != null && !cacheRecord.isStale() )
{ {
Artifact pomArtifact = ArtifactUtils.copyArtifact( cacheRecord.pomArtifact ); Artifact pomArtifact = ArtifactUtils.copyArtifact( cacheRecord.getArtifact() );
Set<Artifact> artifacts = new LinkedHashSet<Artifact>( copyArtifacts( cacheRecord.artifacts ) ); Set<Artifact> artifacts = new LinkedHashSet<Artifact>( copyArtifacts( cacheRecord.getArtifacts() ) );
return new ResolutionGroup( pomArtifact, artifacts , cacheRecord.remoteRepositories ); return new ResolutionGroup( pomArtifact, artifacts , cacheRecord.getRemoteRepositories() );
} }
cache.remove( cacheKey ); cache.remove( cacheKey );
@ -158,4 +214,8 @@ public class DefaultMavenMetadataCache
return result; return result;
} }
public void flush()
{
cache.clear();
}
} }

View File

@ -31,4 +31,5 @@ public interface MavenMetadataCache
void put( Artifact artifact, ArtifactRepository localRepository, void put( Artifact artifact, ArtifactRepository localRepository,
List<ArtifactRepository> remoteRepositories, ResolutionGroup result ); List<ArtifactRepository> remoteRepositories, ResolutionGroup result );
void flush();
} }

View File

@ -40,8 +40,8 @@ import org.apache.maven.model.Dependency;
import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
@ -77,14 +77,12 @@ public class MavenMetadataSource
public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories ) public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
throws ArtifactMetadataRetrievalException throws ArtifactMetadataRetrievalException
{ {
/*
ResolutionGroup cached = cache.get( artifact, localRepository, remoteRepositories ); ResolutionGroup cached = cache.get( artifact, localRepository, remoteRepositories );
if ( cached != null ) if ( cached != null )
{ {
return cached; return cached;
} }
*/
List<Dependency> dependencies; List<Dependency> dependencies;
@ -169,7 +167,7 @@ public class MavenMetadataSource
ResolutionGroup result = new ResolutionGroup( pomArtifact, artifacts, remoteRepositories ); ResolutionGroup result = new ResolutionGroup( pomArtifact, artifacts, remoteRepositories );
//cache.put( artifact, localRepository, remoteRepositories, result ); cache.put( artifact, localRepository, remoteRepositories, result );
return result; return result;
} }

View File

@ -2,10 +2,13 @@ package org.apache.maven;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.DefaultMavenExecutionRequest;
@ -21,6 +24,7 @@ import org.apache.maven.plugin.PluginManager;
import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.repository.DelegatingLocalArtifactRepository;
import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.PlexusTestCase;
@ -77,8 +81,8 @@ public abstract class AbstractCoreMavenComponentTestCase
*/ */
protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
{ {
containerConfiguration.addComponentDiscoverer( PluginManager.class ); // containerConfiguration.addComponentDiscoverer( PluginManager.class );
containerConfiguration.addComponentDiscoveryListener( PluginManager.class ); // containerConfiguration.addComponentDiscoveryListener( PluginManager.class );
} }
protected MavenExecutionRequest createMavenExecutionRequest( File pom ) protected MavenExecutionRequest createMavenExecutionRequest( File pom )
@ -151,6 +155,22 @@ public abstract class AbstractCoreMavenComponentTestCase
return repositorySystem.createDefaultLocalRepository(); return repositorySystem.createDefaultLocalRepository();
} }
protected ArtifactRepository getReactorRepository( MavenProject... projects )
throws InvalidRepositoryException
{
Map<String, MavenProject> projectsMap = new LinkedHashMap<String, MavenProject>();
for ( MavenProject project : projects )
{
projectsMap.put( ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() ), project );
}
DelegatingLocalArtifactRepository delegatingLocalArtifactRepository = new DelegatingLocalArtifactRepository( getLocalRepository() );
delegatingLocalArtifactRepository.setBuildReactor( new ReactorArtifactRepository( projectsMap ) );
return delegatingLocalArtifactRepository;
}
protected class ProjectBuilder protected class ProjectBuilder
{ {
private MavenProject project; private MavenProject project;

View File

@ -1,11 +1,9 @@
package org.apache.maven.plugin; package org.apache.maven.plugin;
import java.util.Set; import java.util.List;
import org.apache.maven.AbstractCoreMavenComponentTestCase; import org.apache.maven.AbstractCoreMavenComponentTestCase;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
@ -66,7 +64,8 @@ public class PluginManagerTest
MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, session.getLocalRepository(), session.getCurrentProject().getRemoteArtifactRepositories() ); MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, session.getLocalRepository(), session.getCurrentProject().getRemoteArtifactRepositories() );
assertNotNull( mojoDescriptor ); assertNotNull( mojoDescriptor );
assertEquals( "generate-metadata", mojoDescriptor.getGoal() ); assertEquals( "generate-metadata", mojoDescriptor.getGoal() );
assertNotNull( mojoDescriptor.getRealm() ); // igorf: plugin realm comes later
// assertNotNull( mojoDescriptor.getRealm() );
PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor(); PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
assertNotNull( pluginDescriptor ); assertNotNull( pluginDescriptor );
@ -226,7 +225,7 @@ public class PluginManagerTest
ArtifactResolutionResult result = repositorySystem.resolve( request ); ArtifactResolutionResult result = repositorySystem.resolve( request );
*/ */
Set<Artifact> artifacts = pluginManager.getPluginArtifacts( pluginArtifact, plugin, getLocalRepository(), getRemoteRepositories() ); List<Artifact> artifacts = pluginManager.getPluginArtifacts( pluginArtifact, plugin, getLocalRepository(), getRemoteRepositories() );
assertEquals( 4, artifacts.size() ); assertEquals( 4, artifacts.size() );
for ( Artifact a : artifacts ) for ( Artifact a : artifacts )

View File

@ -166,6 +166,15 @@ public class MavenCli
MavenExecutionResult result = mavenEmbedder.execute( request ); MavenExecutionResult result = mavenEmbedder.execute( request );
try
{
mavenEmbedder.stop();
}
catch ( MavenEmbedderException e )
{
result.addException( e );
}
// The exception handling should be handled in Maven itself. // The exception handling should be handled in Maven itself.
if ( result.hasExceptions() ) if ( result.hasExceptions() )

View File

@ -37,7 +37,6 @@ import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.apache.maven.model.io.ModelReader; import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.io.ModelWriter; import org.apache.maven.model.io.ModelWriter;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuildingResult; import org.apache.maven.project.MavenProjectBuildingResult;
import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuilder;
@ -355,8 +354,6 @@ public class MavenEmbedder
try try
{ {
ContainerConfiguration cc = new DefaultContainerConfiguration() ContainerConfiguration cc = new DefaultContainerConfiguration()
.addComponentDiscoverer( PluginManager.class )
.addComponentDiscoveryListener( PluginManager.class )
.setClassWorld( classWorld ) .setClassWorld( classWorld )
.setName( "embedder" ); .setName( "embedder" );

View File

@ -39,7 +39,6 @@ import org.apache.maven.model.Build;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectCache;
import org.apache.maven.settings.Profile; import org.apache.maven.settings.Profile;
import org.apache.maven.settings.Repository; import org.apache.maven.settings.Repository;
import org.apache.maven.settings.Settings; import org.apache.maven.settings.Settings;
@ -244,9 +243,6 @@ public class MavenEmbedderTest
assertNull( p0.getProperties().getProperty( "occupation" ) ); assertNull( p0.getProperties().getProperty( "occupation" ) );
// NOTE: The default cache does not consider profiles so clear it to ensure the project is properly rebuild
mavenEmbedder.getPlexusContainer().lookup( MavenProjectCache.class ).clear();
// Check with profile activated // Check with profile activated
MavenExecutionRequest request = new DefaultMavenExecutionRequest() MavenExecutionRequest request = new DefaultMavenExecutionRequest()

View File

@ -64,7 +64,7 @@ import org.apache.maven.model.Scm;
import org.apache.maven.model.Site; import org.apache.maven.model.Site;
import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3Dom;
final class ModelUtils public final class ModelUtils
{ {
// TODO: Replace this with MODELLO-191 // TODO: Replace this with MODELLO-191

View File

@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.model.Plugin;
import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.ComponentSetDescriptor; import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
@ -61,6 +62,8 @@ public class PluginDescriptor
private String description; private String description;
private Plugin plugin;
private Artifact pluginArtifact; private Artifact pluginArtifact;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -307,6 +310,16 @@ public class PluginDescriptor
return description; return description;
} }
public void setPlugin( Plugin plugin )
{
this.plugin = plugin;
}
public Plugin getPlugin()
{
return plugin;
}
public Artifact getPluginArtifact() public Artifact getPluginArtifact()
{ {
return pluginArtifact; return pluginArtifact;

View File

@ -54,7 +54,7 @@ under the License.
<plexusVersion>1.0-beta-3.0.8-SNAPSHOT</plexusVersion> <plexusVersion>1.0-beta-3.0.8-SNAPSHOT</plexusVersion>
<plexusInterpolationVersion>1.8.1</plexusInterpolationVersion> <plexusInterpolationVersion>1.8.1</plexusInterpolationVersion>
<plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion> <plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
<plexusUtilsVersion>1.5.8</plexusUtilsVersion> <plexusUtilsVersion>1.5.13-SNAPSHOT</plexusUtilsVersion>
<plexusJetty6Version>1.6</plexusJetty6Version> <plexusJetty6Version>1.6</plexusJetty6Version>
<plexusWebdavVersion>1.0</plexusWebdavVersion> <plexusWebdavVersion>1.0</plexusWebdavVersion>
<wagonVersion>1.0-beta-5</wagonVersion> <wagonVersion>1.0-beta-5</wagonVersion>