From 1420d61c05f0719ff59417430906954a4cc58ff6 Mon Sep 17 00:00:00 2001 From: Igor Fedorenko Date: Wed, 24 Dec 2014 09:23:55 -0500 Subject: [PATCH] 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 --- .../plugin/DefaultExtensionRealmCache.java | 11 +- .../plugin/DefaultPluginArtifactsCache.java | 2 +- .../maven/plugin/ExtensionRealmCache.java | 12 +- .../maven/plugin/MavenPluginManager.java | 10 + .../maven/plugin/PluginArtifactsCache.java | 2 +- .../internal/DefaultMavenPluginManager.java | 261 ++++++++++++++++-- .../project/DefaultModelBuildingListener.java | 7 + .../project/DefaultProjectBuildingHelper.java | 146 ++-------- .../project/ExtensionDescriptorBuilder.java | 2 +- .../maven/project/ProjectBuildingHelper.java | 3 +- 10 files changed, 288 insertions(+), 168 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java index bda84d0081..c9df92c6fa 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java @@ -25,13 +25,13 @@ import java.util.List; 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 @@ public class DefaultExtensionRealmCache private final int hashCode; - public CacheKey( List extensionArtifacts ) + public CacheKey( List extensionArtifacts ) { this.files = new ArrayList( extensionArtifacts.size() ); this.timestamps = new ArrayList( extensionArtifacts.size() ); @@ -110,7 +110,7 @@ public class DefaultExtensionRealmCache protected final Map cache = new ConcurrentHashMap(); @Override - public Key createKey( List extensionArtifacts ) + public Key createKey( List extensionArtifacts ) { return new CacheKey( extensionArtifacts ); } @@ -120,7 +120,8 @@ public class DefaultExtensionRealmCache return cache.get( key ); } - public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor ) + public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor, + List artifacts ) { if ( extensionRealm == null ) { @@ -132,7 +133,7 @@ public class DefaultExtensionRealmCache 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 ); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java index 6ee3463c6a..23bda64d2f 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java @@ -25,11 +25,11 @@ import java.util.List; 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; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java b/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java index 3dfb5fddbb..d50df0e94f 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java @@ -21,10 +21,10 @@ package org.apache.maven.plugin; 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. Warning: This is an internal utility interface that is only public @@ -51,19 +51,23 @@ public interface ExtensionRealmCache public final ExtensionDescriptor desciptor; - public CacheRecord( ClassRealm realm, ExtensionDescriptor descriptor ) + public final List artifacts; + + public CacheRecord( ClassRealm realm, ExtensionDescriptor descriptor, List artifacts ) { this.realm = realm; this.desciptor = descriptor; + this.artifacts = artifacts; } } - Key createKey( List extensionArtifacts ); + Key createKey( List extensionArtifacts ); CacheRecord get( Key key ); - CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor ); + CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor, + List artifacts ); void flush(); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java index 8f6c3a87e9..a1314fc009 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java @@ -25,6 +25,7 @@ import org.apache.maven.execution.MavenSession; 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 @@ public interface MavenPluginManager List 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 diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java index 1232052723..17537a298e 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java @@ -21,10 +21,10 @@ package org.apache.maven.plugin; 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; diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index 842987b8bd..c815920805 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -46,17 +46,20 @@ 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; @@ -65,6 +68,12 @@ 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; @@ -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 repositories, @@ -355,45 +384,72 @@ public class DefaultMavenPluginManager MavenProject project = session.getCurrentProject(); - DependencyFilter dependencyFilter = project.getExtensionDependencyFilter(); - dependencyFilter = AndDependencyFilter.newInstance( dependencyFilter, filter ); + final ClassRealm pluginRealm; + final List pluginArtifacts; - DependencyNode root = - pluginDependenciesResolver.resolve( plugin, RepositoryUtils.toArtifact( pluginArtifact ), dependencyFilter, - project.getRemotePluginRepositories(), session.getRepositorySession() ); - - PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); - root.accept( nlg ); - - List exposedPluginArtifacts = new ArrayList( nlg.getNodes().size() ); - RepositoryUtils.toArtifacts( exposedPluginArtifacts, Collections.singleton( root ), - Collections.emptyList(), null ); - for ( Iterator 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 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 @@ public class DefaultMavenPluginManager } } + 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 artifacts; + } + private Map calcImports( MavenProject project, ClassLoader parent, List imports ) { Map foreignImports = new HashMap(); @@ -725,4 +801,137 @@ public class DefaultMavenPluginManager } } + 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.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 resolveExtensionArtifacts( Plugin extensionPlugin, List repositories, + RepositorySystemSession session ) + throws PluginResolutionException + { + DependencyNode root = pluginDependenciesResolver.resolve( extensionPlugin, null, null, repositories, session ); + PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); + root.accept( nlg ); + return toMavenArtifacts( root, nlg ); + } + } diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java index 5d97cfcafa..262cf090d7 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java @@ -28,6 +28,7 @@ import org.apache.maven.model.building.ModelBuildingEvent; 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 @@ class DefaultModelBuildingListener .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 ); } diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java index 035b42b5dd..aea8fdbecb 100644 --- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java +++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java @@ -19,7 +19,6 @@ package org.apache.maven.project; * 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.List; 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. Warning: 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 createArtifactRepositories( List pomRepositories, List externalRepositories, @@ -165,7 +145,7 @@ public class DefaultProjectBuildingHelper 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 class DefaultProjectBuildingHelper 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 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 artifacts = recordRealm.artifacts; extensionRealms.add( extensionRealm ); if ( extensionDescriptor != null ) @@ -334,7 +230,7 @@ public class DefaultProjectBuildingHelper if ( record == null ) { - projectRealm = classRealmManager.createProjectRealm( model, publicArtifacts ); + projectRealm = classRealmManager.createProjectRealm( model, toAetherArtifacts( publicArtifacts ) ); Set exclusions = new LinkedHashSet(); @@ -379,19 +275,6 @@ public class DefaultProjectBuildingHelper return record; } - private List resolveExtensionArtifacts( Plugin extensionPlugin, List 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 class DefaultProjectBuildingHelper Thread.currentThread().setContextClassLoader( projectRealm ); } + private List toAetherArtifacts( final List pluginArtifacts ) + { + return new ArrayList( RepositoryUtils.toArtifacts( pluginArtifacts ) ); + } + } diff --git a/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java b/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java index c18f87f961..cebb63097f 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java @@ -40,7 +40,7 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException; * * @author Benjamin Bentmann */ -class ExtensionDescriptorBuilder +public class ExtensionDescriptorBuilder { private String getExtensionDescriptorLocation() diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java index 52b3a8810a..45fff6e638 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java +++ b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java @@ -25,6 +25,7 @@ import org.apache.maven.artifact.InvalidRepositoryException; 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 @@ public interface ProjectBuildingHelper */ 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