MNG-5742 fixed duplicate plugin realms when extensions=true

Consolidated plugin realm setup logic in DefaultMavenPluginManager.
Extensions realm is fully setup during project loading and the same
realm is used to both load extensions and execute plugin goals now.

Signed-off-by: Igor Fedorenko <ifedorenko@apache.org>
This commit is contained in:
Igor Fedorenko 2014-12-24 09:23:55 -05:00
parent dbecf3b5cd
commit 1420d61c05
10 changed files with 288 additions and 168 deletions

View File

@ -25,13 +25,13 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.ExtensionDescriptor;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
import org.eclipse.aether.artifact.Artifact;
/**
* Default extension realm cache implementation. Assumes cached data does not change.
@ -55,7 +55,7 @@ protected static class CacheKey
private final int hashCode;
public CacheKey( List<? extends Artifact> extensionArtifacts )
public CacheKey( List<Artifact> extensionArtifacts )
{
this.files = new ArrayList<File>( extensionArtifacts.size() );
this.timestamps = new ArrayList<Long>( extensionArtifacts.size() );
@ -110,7 +110,7 @@ public String toString()
protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
@Override
public Key createKey( List<? extends Artifact> extensionArtifacts )
public Key createKey( List<Artifact> extensionArtifacts )
{
return new CacheKey( extensionArtifacts );
}
@ -120,7 +120,8 @@ public CacheRecord get( Key key )
return cache.get( key );
}
public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor )
public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor,
List<Artifact> artifacts )
{
if ( extensionRealm == null )
{
@ -132,7 +133,7 @@ public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor
throw new IllegalStateException( "Duplicate extension realm for extension " + key );
}
CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor );
CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor, artifacts );
cache.put( key, record );

View File

@ -25,11 +25,11 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;

View File

@ -21,10 +21,10 @@
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.ExtensionDescriptor;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.eclipse.aether.artifact.Artifact;
/**
* Caches extension class realms. <strong>Warning:</strong> This is an internal utility interface that is only public
@ -51,19 +51,23 @@ static class CacheRecord
public final ExtensionDescriptor desciptor;
public CacheRecord( ClassRealm realm, ExtensionDescriptor descriptor )
public final List<Artifact> artifacts;
public CacheRecord( ClassRealm realm, ExtensionDescriptor descriptor, List<Artifact> artifacts )
{
this.realm = realm;
this.desciptor = descriptor;
this.artifacts = artifacts;
}
}
Key createKey( List<? extends Artifact> extensionArtifacts );
Key createKey( List<Artifact> extensionArtifacts );
CacheRecord get( Key key );
CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor );
CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor,
List<Artifact> artifacts );
void flush();

View File

@ -25,6 +25,7 @@
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.repository.RemoteRepository;
@ -91,6 +92,15 @@ void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session,
List<String> imports, DependencyFilter filter )
throws PluginResolutionException, PluginContainerException;
/**
* Sets up class realm for the specified build extensions plugin.
*
* @since 3.2.6
*/
ExtensionRealmCache.CacheRecord setupExtensionsRealm( MavenProject project, Plugin plugin,
RepositorySystemSession session )
throws PluginManagerException;
/**
* Looks up the mojo for the specified mojo execution and populates its parameters from the configuration given by
* the mojo execution. The mojo/plugin descriptor associated with the mojo execution provides the class realm to

View File

@ -21,10 +21,10 @@
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.repository.RemoteRepository;

View File

@ -46,17 +46,20 @@
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;
@ -65,6 +68,12 @@
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;
@ -111,6 +120,15 @@ 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.
*
* @noreference this is part of internal implementation and may be changed or removed without notice
* @since 3.2.6
*/
public static final String KEY_EXTENSIONS_REALMS = DefaultMavenPluginManager.class.getName() + "/extensionsRealms";
@Requirement
private Logger logger;
@ -135,6 +153,17 @@ public class DefaultMavenPluginManager
@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<RemoteRepository> repositories,
@ -355,45 +384,72 @@ private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession
MavenProject project = session.getCurrentProject();
DependencyFilter dependencyFilter = project.getExtensionDependencyFilter();
dependencyFilter = AndDependencyFilter.newInstance( dependencyFilter, filter );
final ClassRealm pluginRealm;
final List<Artifact> pluginArtifacts;
DependencyNode root =
pluginDependenciesResolver.resolve( plugin, RepositoryUtils.toArtifact( pluginArtifact ), dependencyFilter,
project.getRemotePluginRepositories(), session.getRepositorySession() );
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
root.accept( nlg );
List<Artifact> exposedPluginArtifacts = new ArrayList<Artifact>( nlg.getNodes().size() );
RepositoryUtils.toArtifacts( exposedPluginArtifacts, Collections.singleton( root ),
Collections.<String>emptyList(), null );
for ( Iterator<Artifact> it = exposedPluginArtifacts.iterator(); it.hasNext(); )
RepositorySystemSession repositorySession = session.getRepositorySession();
if ( plugin.isExtensions() )
{
Artifact artifact = it.next();
if ( artifact.getFile() == null )
// TODO discover components in #setupExtensionsRealm
ExtensionRealmCache.CacheRecord extensionRecord;
try
{
it.remove();
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 );
}
pluginRealm = extensionRecord.realm;
pluginArtifacts = extensionRecord.artifacts;
}
else
{
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 );
}
List<org.eclipse.aether.artifact.Artifact> pluginArtifacts = nlg.getArtifacts( true );
ClassRealm pluginRealm =
classRealmManager.createPluginRealm( plugin, parent, null, foreignImports, pluginArtifacts );
pluginDescriptor.setClassRealm( pluginRealm );
pluginDescriptor.setArtifacts( exposedPluginArtifacts );
pluginDescriptor.setArtifacts( pluginArtifacts );
}
private void discoverPluginComponents( final ClassRealm pluginRealm, Plugin plugin,
PluginDescriptor pluginDescriptor )
throws PluginContainerException
{
try
{
for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
if ( pluginDescriptor != null )
{
componentDescriptor.setRealm( pluginRealm );
container.addComponentDescriptor( componentDescriptor );
for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
{
componentDescriptor.setRealm( pluginRealm );
container.addComponentDescriptor( componentDescriptor );
}
}
( (DefaultPlexusContainer) container ).discoverComponents( pluginRealm, new SessionScopeModule( container ),
( (DefaultPlexusContainer) container ).discoverComponents( pluginRealm,
new SessionScopeModule( container ),
new MojoExecutionScopeModule( container ) );
}
catch ( ComponentLookupException e )
@ -408,6 +464,26 @@ private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession
}
}
private List<org.eclipse.aether.artifact.Artifact> toAetherArtifacts( final List<Artifact> pluginArtifacts )
{
return new ArrayList<org.eclipse.aether.artifact.Artifact>( RepositoryUtils.toArtifacts( pluginArtifacts ) );
}
private List<Artifact> toMavenArtifacts( DependencyNode root, PreorderNodeListGenerator nlg )
{
List<Artifact> artifacts = new ArrayList<Artifact>( nlg.getNodes().size() );
RepositoryUtils.toArtifacts( artifacts, Collections.singleton( root ), Collections.<String>emptyList(), null );
for ( Iterator<Artifact> it = artifacts.iterator(); it.hasNext(); )
{
Artifact artifact = it.next();
if ( artifact.getFile() == null )
{
it.remove();
}
}
return artifacts;
}
private Map<String, ClassLoader> calcImports( MavenProject project, ClassLoader parent, List<String> imports )
{
Map<String, ClassLoader> foreignImports = new HashMap<String, ClassLoader>();
@ -725,4 +801,137 @@ public void releaseMojo( Object mojo, MojoExecution mojoExecution )
}
}
public ExtensionRealmCache.CacheRecord setupExtensionsRealm( MavenProject project, Plugin plugin,
RepositorySystemSession session )
throws PluginManagerException
{
@SuppressWarnings( "unchecked" )
Map<String, ExtensionRealmCache.CacheRecord> pluginRealms =
(Map<String, ExtensionRealmCache.CacheRecord>) project.getContextValue( KEY_EXTENSIONS_REALMS );
if ( pluginRealms == null )
{
pluginRealms = new HashMap<String, ExtensionRealmCache.CacheRecord>();
project.setContextValue( KEY_EXTENSIONS_REALMS, pluginRealms );
}
final String pluginKey = plugin.getId();
ExtensionRealmCache.CacheRecord extensionRecord = pluginRealms.get( pluginKey );
if ( extensionRecord != null )
{
return extensionRecord;
}
final List<RemoteRepository> 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<Artifact> 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.artifacts;
}
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 ) );
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 e )
{
// ignore, see above
}
catch ( 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<Artifact> resolveExtensionArtifacts( Plugin extensionPlugin, List<RemoteRepository> 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 );
}
}

View File

@ -28,6 +28,7 @@
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
@ -125,6 +126,12 @@ public void buildExtensionsAssembled( ModelBuildingEvent event )
.setMessage( "Unresolveable build extension: " + e.getMessage() )
.setException( e ) );
}
catch ( PluginManagerException e )
{
event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
.setMessage( "Unresolveable build extension: " + e.getMessage() )
.setException( e ) );
}
projectBuildingHelper.selectProjectRealm( project );
}

View File

@ -19,7 +19,6 @@
* under the License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -30,37 +29,29 @@
import java.util.Map;
import java.util.Set;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.classrealm.ClassRealmManager;
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
import org.apache.maven.model.Build;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Repository;
import org.apache.maven.plugin.ExtensionRealmCache;
import org.apache.maven.plugin.PluginArtifactsCache;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.internal.PluginDependenciesResolver;
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionRequest;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.plugin.version.PluginVersionResolver;
import org.apache.maven.repository.RepositorySystem;
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.logging.Logger;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
/**
* Assists the project builder. <strong>Warning:</strong> This is an internal utility class that is only public for
@ -83,12 +74,6 @@ public class DefaultProjectBuildingHelper
@Requirement
private ClassRealmManager classRealmManager;
@Requirement
private PluginArtifactsCache pluginArtifactsCache;
@Requirement
private ExtensionRealmCache extensionRealmCache;
@Requirement
private ProjectRealmCache projectRealmCache;
@ -96,12 +81,7 @@ public class DefaultProjectBuildingHelper
private RepositorySystem repositorySystem;
@Requirement
private PluginVersionResolver pluginVersionResolver;
@Requirement
private PluginDependenciesResolver pluginDependenciesResolver;
private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
private MavenPluginManager pluginManager;
public List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
List<ArtifactRepository> externalRepositories,
@ -165,7 +145,7 @@ public List<ArtifactRepository> createArtifactRepositories( List<Repository> pom
public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProject project, Model model,
ProjectBuildingRequest request )
throws PluginResolutionException, PluginVersionResolutionException
throws PluginResolutionException, PluginVersionResolutionException, PluginManagerException
{
ClassRealm projectRealm;
@ -213,96 +193,12 @@ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProje
for ( Plugin plugin : extensionPlugins )
{
if ( plugin.getVersion() == null )
{
PluginVersionRequest versionRequest =
new DefaultPluginVersionRequest( plugin, request.getRepositorySession(),
project.getRemotePluginRepositories() );
plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
}
ExtensionRealmCache.CacheRecord recordRealm =
pluginManager.setupExtensionsRealm( project, plugin, request.getRepositorySession() );
List<Artifact> artifacts;
PluginArtifactsCache.Key cacheKey =
pluginArtifactsCache.createKey( plugin, null, project.getRemotePluginRepositories(),
request.getRepositorySession() );
PluginArtifactsCache.CacheRecord recordArtifacts = pluginArtifactsCache.get( cacheKey );
if ( recordArtifacts != null )
{
artifacts = recordArtifacts.artifacts;
}
else
{
try
{
artifacts = resolveExtensionArtifacts( plugin, project.getRemotePluginRepositories(), request );
recordArtifacts = pluginArtifactsCache.put( cacheKey, artifacts );
}
catch ( PluginResolutionException e )
{
pluginArtifactsCache.put( cacheKey, e );
pluginArtifactsCache.register( project, cacheKey, recordArtifacts );
throw e;
}
}
pluginArtifactsCache.register( project, cacheKey, recordArtifacts );
ClassRealm extensionRealm;
ExtensionDescriptor extensionDescriptor = null;
final ExtensionRealmCache.Key extensionKey = extensionRealmCache.createKey( artifacts );
ExtensionRealmCache.CacheRecord recordRealm = extensionRealmCache.get( extensionKey );
if ( recordRealm != null )
{
extensionRealm = recordRealm.realm;
extensionDescriptor = recordRealm.desciptor;
}
else
{
extensionRealm = classRealmManager.createExtensionRealm( plugin, artifacts );
try
{
( (DefaultPlexusContainer) container ).discoverComponents( extensionRealm,
new SessionScopeModule( container ),
new MojoExecutionScopeModule( container ) );
}
catch ( Exception e )
{
throw new IllegalStateException( "Failed to discover components in extension realm "
+ extensionRealm.getId(), e );
}
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 );
}
}
recordRealm = extensionRealmCache.put( extensionKey, extensionRealm, extensionDescriptor );
}
extensionRealmCache.register( project, extensionKey, recordRealm );
final ClassRealm extensionRealm = recordRealm.realm;
final ExtensionDescriptor extensionDescriptor = recordRealm.desciptor;
final List<Artifact> artifacts = recordRealm.artifacts;
extensionRealms.add( extensionRealm );
if ( extensionDescriptor != null )
@ -334,7 +230,7 @@ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProje
if ( record == null )
{
projectRealm = classRealmManager.createProjectRealm( model, publicArtifacts );
projectRealm = classRealmManager.createProjectRealm( model, toAetherArtifacts( publicArtifacts ) );
Set<String> exclusions = new LinkedHashSet<String>();
@ -379,19 +275,6 @@ record = projectRealmCache.put( projectRealmKey, projectRealm, extensionArtifact
return record;
}
private List<Artifact> resolveExtensionArtifacts( Plugin extensionPlugin, List<RemoteRepository> repositories,
ProjectBuildingRequest request )
throws PluginResolutionException
{
DependencyNode root =
pluginDependenciesResolver.resolve( extensionPlugin, null, null, repositories,
request.getRepositorySession() );
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
root.accept( nlg );
return nlg.getArtifacts( false );
}
public void selectProjectRealm( MavenProject project )
{
ClassLoader projectRealm = project.getClassRealm();
@ -404,4 +287,9 @@ public void selectProjectRealm( MavenProject project )
Thread.currentThread().setContextClassLoader( projectRealm );
}
private List<org.eclipse.aether.artifact.Artifact> toAetherArtifacts( final List<Artifact> pluginArtifacts )
{
return new ArrayList<org.eclipse.aether.artifact.Artifact>( RepositoryUtils.toArtifacts( pluginArtifacts ) );
}
}

View File

@ -40,7 +40,7 @@
*
* @author Benjamin Bentmann
*/
class ExtensionDescriptorBuilder
public class ExtensionDescriptorBuilder
{
private String getExtensionDescriptorLocation()

View File

@ -25,6 +25,7 @@
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
@ -66,7 +67,7 @@ List<ArtifactRepository> createArtifactRepositories( List<Repository> pomReposit
*/
ProjectRealmCache.CacheRecord createProjectRealm( MavenProject project, Model model,
ProjectBuildingRequest request )
throws PluginResolutionException, PluginVersionResolutionException;
throws PluginResolutionException, PluginVersionResolutionException, PluginManagerException;
/**
* Updates the context class loader such that the container will search the project realm when the model builder