diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
index 85919fcf27..0545b7eca9 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -18,6 +18,7 @@ package org.apache.maven;
import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.context.BuildContextManager;
@@ -30,7 +31,11 @@ import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.execution.RuntimeInformation;
+import org.apache.maven.extension.ExtensionManager;
import org.apache.maven.lifecycle.LifecycleExecutor;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.MavenEvents;
@@ -41,11 +46,15 @@ import org.apache.maven.project.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.build.model.ModelLineage;
+import org.apache.maven.project.build.model.ModelLineageBuilder;
+import org.apache.maven.project.build.model.ModelLineageIterator;
import org.apache.maven.reactor.MavenExecutionException;
import org.apache.maven.settings.Settings;
import org.apache.maven.usability.diagnostics.ErrorDiagnostics;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
@@ -60,8 +69,10 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.TimeZone;
/**
@@ -77,6 +88,10 @@ public class DefaultMaven
// Components
// ----------------------------------------------------------------------
+ protected ExtensionManager extensionManager;
+
+ protected ModelLineageBuilder modelLineageBuilder;
+
protected BuildContextManager buildContextManager;
protected MavenProjectBuilder projectBuilder;
@@ -337,6 +352,8 @@ public class DefaultMaven
throw new MavenExecutionException( "Error selecting project files for the reactor: " + e.getMessage(), e );
}
+ scanProjectsForExtensions( files, request, globalProfileManager );
+
try
{
projects = collectProjects( files, request.getLocalRepository(), request.isRecursive(),
@@ -358,6 +375,91 @@ public class DefaultMaven
return projects;
}
+ // TODO: We should probably do this discovery just-in-time, if we can move to building project
+ // instances just-in-time.
+ private void scanProjectsForExtensions( List files, MavenExecutionRequest request,
+ ProfileManager globalProfileManager )
+ throws MavenExecutionException
+ {
+ MavenProject superProject;
+ try
+ {
+ superProject = projectBuilder.buildStandaloneSuperProject( request.getLocalRepository(),
+ globalProfileManager );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw new MavenExecutionException( "Error building super-POM for retrieving the default remote repository list: " + e.getMessage(), e );
+ }
+
+ List originalRemoteRepositories = superProject.getRemoteArtifactRepositories();
+ Map cache = new HashMap();
+
+ for ( Iterator it = files.iterator(); it.hasNext(); )
+ {
+ File pom = (File) it.next();
+
+ ModelLineage lineage;
+ try
+ {
+ lineage = modelLineageBuilder.buildModelLineage( pom, request.getLocalRepository(), originalRemoteRepositories, globalProfileManager, cache );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw new MavenExecutionException( "Error building model lineage in order to pre-scan for extensions: " + e.getMessage(), e );
+ }
+
+ for ( ModelLineageIterator lineageIterator = lineage.lineageIterator(); lineageIterator.hasNext(); )
+ {
+ Model model = (Model) lineageIterator.next();
+
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ List extensions = build.getExtensions();
+
+ if ( extensions != null && !extensions.isEmpty() )
+ {
+ List remoteRepositories = lineageIterator.getArtifactRepositories();
+
+ // thankfully, we don't have to deal with dependencyManagement here, yet.
+ // TODO Revisit if/when extensions are made to use the info in dependencyManagement
+ for ( Iterator extensionIterator = extensions.iterator(); extensionIterator.hasNext(); )
+ {
+ Extension extension = (Extension) extensionIterator.next();
+
+ try
+ {
+ extensionManager.addExtension( extension, model, remoteRepositories, request.getLocalRepository() );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ throw new MavenExecutionException( "Cannot resolve pre-scanned extension artifact: "
+ + extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
+ e );
+ }
+ catch ( ArtifactNotFoundException e )
+ {
+ throw new MavenExecutionException( "Cannot find pre-scanned extension artifact: "
+ + extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
+ e );
+ }
+ catch ( PlexusContainerException e )
+ {
+ throw new MavenExecutionException( "Failed to add pre-scanned extension: "
+ + extension.getGroupId() + ":" + extension.getArtifactId() + ": " + e.getMessage(),
+ e );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ extensionManager.registerWagons();
+ }
+
private void logReactorSummaryLine( String name,
String status )
{
diff --git a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java
index b12caea314..dc47fa037b 100644
--- a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java
+++ b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java
@@ -19,6 +19,7 @@ package org.apache.maven.extension;
import org.apache.maven.ArtifactFilterManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -28,6 +29,8 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
import org.apache.maven.project.MavenProject;
import org.apache.maven.wagon.Wagon;
import org.codehaus.plexus.PlexusConstants;
@@ -41,6 +44,7 @@ import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
/**
@@ -55,6 +59,8 @@ public class DefaultExtensionManager
implements ExtensionManager, Contextualizable
{
+ private ArtifactFactory artifactFactory;
+
private ArtifactResolver artifactResolver;
private ArtifactMetadataSource artifactMetadataSource;
@@ -65,6 +71,33 @@ public class DefaultExtensionManager
private WagonManager wagonManager;
+ public void addExtension( Extension extension, Model originatingModel, List remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
+ {
+ Artifact extensionArtifact = artifactFactory.createBuildArtifact( extension.getGroupId(), extension.getArtifactId(), extension.getVersion(), "jar" );
+
+ Parent originatingParent = originatingModel.getParent();
+
+ String groupId = originatingModel.getGroupId();
+ if ( groupId == null && originatingParent != null )
+ {
+ groupId = originatingParent.getGroupId();
+ }
+
+ String artifactId = originatingModel.getArtifactId();
+
+ String version = originatingModel.getVersion();
+ if ( version == null && originatingParent != null )
+ {
+ version = originatingParent.getVersion();
+ }
+
+ Artifact projectArtifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
+
+ addExtension( extensionArtifact, projectArtifact, remoteRepositories, localRepository, null );
+ }
+
public void addExtension( Extension extension, MavenProject project, ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
{
@@ -73,22 +106,33 @@ public class DefaultExtensionManager
getLogger().debug( "Initialising extension: " + extensionId );
Artifact artifact = (Artifact) project.getExtensionArtifactMap().get( extensionId );
-
- if ( artifact != null )
+
+ addExtension( artifact, project.getArtifact(), project.getRemoteArtifactRepositories(), localRepository,
+ new ActiveArtifactResolver( project ) );
+ }
+
+ private void addExtension( Artifact extensionArtifact, Artifact projectArtifact, List remoteRepositories,
+ ArtifactRepository localRepository, ActiveArtifactResolver activeArtifactResolver )
+ throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException
+ {
+ if ( extensionArtifact != null )
{
- ArtifactFilter filter = new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), project.getArtifact() );
+ ArtifactFilter filter = new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), projectArtifact );
- ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( artifact ),
- project.getArtifact(),
+ ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( extensionArtifact ),
+ projectArtifact,
localRepository,
- project.getRemoteArtifactRepositories(),
+ remoteRepositories,
artifactMetadataSource, filter );
for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
{
Artifact a = (Artifact) i.next();
- a = project.replaceWithActiveArtifact( a );
+ if ( activeArtifactResolver != null )
+ {
+ a = activeArtifactResolver.replaceWithActiveArtifact( a );
+ }
getLogger().debug( "Adding to extension classpath: " + a.getFile() );
@@ -116,6 +160,21 @@ public class DefaultExtensionManager
{
this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
}
+
+ private static final class ActiveArtifactResolver
+ {
+ private MavenProject project;
+
+ ActiveArtifactResolver( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ Artifact replaceWithActiveArtifact( Artifact artifact )
+ {
+ return project.replaceWithActiveArtifact( artifact );
+ }
+ }
private static final class ProjectArtifactExceptionFilter
implements ArtifactFilter
@@ -137,4 +196,5 @@ public class DefaultExtensionManager
return projectDependencyConflictId.equals( depConflictId ) || passThroughFilter.include( artifact );
}
}
+
}
diff --git a/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java b/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java
index cc4d6ec383..b875c2e290 100644
--- a/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java
+++ b/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java
@@ -20,9 +20,12 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.PlexusContainerException;
+import java.util.List;
+
/**
* Used to locate extensions.
*
@@ -35,4 +38,8 @@ public interface ExtensionManager
throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException;
void registerWagons();
+
+ void addExtension( Extension extension, Model originatingModel, List remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, PlexusContainerException, ArtifactNotFoundException;
}
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
index 5189172e2a..2de388fd26 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
@@ -24,9 +24,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
-import org.apache.maven.extension.ExtensionManager;
import org.apache.maven.lifecycle.mapping.LifecycleMapping;
-import org.apache.maven.model.Extension;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.ReportPlugin;
@@ -51,7 +49,6 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.settings.Settings;
-import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.StringUtils;
@@ -85,8 +82,6 @@ public class DefaultLifecycleExecutor
private PluginManager pluginManager;
- private ExtensionManager extensionManager;
-
private List lifecycles;
private ArtifactHandlerManager artifactHandlerManager;
@@ -134,54 +129,20 @@ public class DefaultLifecycleExecutor
List taskSegments = segmentTaskListByAggregationNeeds( goals, session, rootProject );
// TODO: probably don't want to do all this up front
- findExtensions( session );
+ try
+ {
+ Map handlers = findArtifactTypeHandlers( session );
+
+ artifactHandlerManager.addHandlers( handlers );
+ }
+ catch ( PluginNotFoundException e )
+ {
+ throw new LifecycleExecutionException( e.getMessage(), e );
+ }
executeTaskSegments( taskSegments, rm, session, rootProject, dispatcher );
}
- private void findExtensions( MavenSession session )
- throws LifecycleExecutionException
- {
- for ( Iterator i = session.getSortedProjects().iterator(); i.hasNext(); )
- {
- MavenProject project = (MavenProject) i.next();
-
- for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
- {
- Extension extension = (Extension) j.next();
- try
- {
- extensionManager.addExtension( extension, project, session.getLocalRepository() );
- }
- catch ( PlexusContainerException e )
- {
- throw new LifecycleExecutionException( "Unable to initialise extensions", e );
- }
- catch ( ArtifactResolutionException e )
- {
- throw new LifecycleExecutionException( e.getMessage(), e );
- }
- catch ( ArtifactNotFoundException e )
- {
- throw new LifecycleExecutionException( e.getMessage(), e );
- }
- }
-
- extensionManager.registerWagons();
-
- try
- {
- Map handlers = findArtifactTypeHandlers( project, session );
-
- artifactHandlerManager.addHandlers( handlers );
- }
- catch ( PluginNotFoundException e )
- {
- throw new LifecycleExecutionException( e.getMessage(), e );
- }
- }
- }
-
private void executeTaskSegments( List taskSegments, ReactorManager rm, MavenSession session,
MavenProject rootProject, EventDispatcher dispatcher )
throws LifecycleExecutionException, BuildFailureException
@@ -1154,42 +1115,49 @@ public class DefaultLifecycleExecutor
/**
* @todo Not particularly happy about this. Would like WagonManager and ArtifactTypeHandlerManager to be able to
* lookup directly, or have them passed in
+ *
+ * @todo Move this sort of thing to the tail end of the project-building process
*/
- private Map findArtifactTypeHandlers( MavenProject project, MavenSession session )
+ private Map findArtifactTypeHandlers( MavenSession session )
throws LifecycleExecutionException, PluginNotFoundException
{
Map map = new HashMap();
- for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
+ for ( Iterator projectIterator = session.getSortedProjects().iterator(); projectIterator.hasNext(); )
{
- Plugin plugin = (Plugin) i.next();
-
- if ( plugin.isExtensions() )
+ MavenProject project = (MavenProject) projectIterator.next();
+
+ for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
{
- verifyPlugin( plugin, project, session );
+ Plugin plugin = (Plugin) i.next();
- // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
- try
+ if ( plugin.isExtensions() )
{
- Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
- map.putAll( components );
- }
- catch ( ComponentLookupException e )
- {
- getLogger().debug( "Unable to find the lifecycle component in the extension", e );
- }
- catch ( PluginManagerException e )
- {
- throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
- plugin.getKey() + "': " + e.getMessage(), e );
- }
+ verifyPlugin( plugin, project, session );
- // shudder...
- for ( Iterator j = map.values().iterator(); j.hasNext(); )
- {
- ArtifactHandler handler = (ArtifactHandler) j.next();
- if ( project.getPackaging().equals( handler.getPackaging() ) )
+ // TODO: if moved to the plugin manager we already have the descriptor from above and so do can lookup the container directly
+ try
{
- project.getArtifact().setArtifactHandler( handler );
+ Map components = pluginManager.getPluginComponents( plugin, ArtifactHandler.ROLE );
+ map.putAll( components );
+ }
+ catch ( ComponentLookupException e )
+ {
+ getLogger().debug( "Unable to find the lifecycle component in the extension", e );
+ }
+ catch ( PluginManagerException e )
+ {
+ throw new LifecycleExecutionException( "Error looking up available components from plugin '" +
+ plugin.getKey() + "': " + e.getMessage(), e );
+ }
+
+ // shudder...
+ for ( Iterator j = map.values().iterator(); j.hasNext(); )
+ {
+ ArtifactHandler handler = (ArtifactHandler) j.next();
+ if ( project.getPackaging().equals( handler.getPackaging() ) )
+ {
+ project.getArtifact().setArtifactHandler( handler );
+ }
}
}
}
diff --git a/maven-core/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/main/resources/META-INF/plexus/components.xml
index 93dca1de8f..164bb880cf 100644
--- a/maven-core/src/main/resources/META-INF/plexus/components.xml
+++ b/maven-core/src/main/resources/META-INF/plexus/components.xml
@@ -48,6 +48,9 @@
org.apache.maven.ArtifactFilterManager
+
+ org.apache.maven.artifact.factory.ArtifactFactory
+
org.apache.maven.artifact.resolver.ArtifactResolver
@@ -80,6 +83,13 @@
org.apache.maven.Maven
org.apache.maven.DefaultMaven
+
+ org.apache.maven.extension.ExtensionManager
+
+
+ org.apache.maven.project.build.model.ModelLineageBuilder
+ default
+
org.apache.maven.context.BuildContextManager
default
@@ -206,9 +216,6 @@
org.apache.maven.plugin.PluginManager
-
- org.apache.maven.extension.ExtensionManager
-
org.apache.maven.artifact.handler.manager.ArtifactHandlerManager