diff --git a/maven-core/src/main/aspect/org/apache/maven/errors/LifecycleErrorReporterAspect.aj b/maven-core/src/main/aspect/org/apache/maven/errors/LifecycleErrorReporterAspect.aj index cc237e48c8..106e654bd6 100644 --- a/maven-core/src/main/aspect/org/apache/maven/errors/LifecycleErrorReporterAspect.aj +++ b/maven-core/src/main/aspect/org/apache/maven/errors/LifecycleErrorReporterAspect.aj @@ -295,8 +295,8 @@ public privileged aspect LifecycleErrorReporterAspect MavenSession session ) throws LifecycleLoaderException, LifecycleSpecificationException, LifecyclePlannerException: cflow( execution( * DefaultLifecycleExecutor.*( .. ) ) ) - && execution( BuildPlan BuildPlanner+.constructBuildPlan( List, MavenProject, MavenSession ) ) - && args( tasks, project, session ) + && execution( BuildPlan BuildPlanner+.constructBuildPlan( List, MavenProject, MavenSession, * ) ) + && args( tasks, project, session, * ) { try { 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 6e9ecbe21b..74217baaa9 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 @@ -177,7 +177,7 @@ public class DefaultLifecycleExecutor if ( segment.aggregate() ) { - executeTaskSegmentsForProject( segment, rootProject, reactorManager, dispatcher, session ); + executeTaskSegmentForProject( segment, rootProject, reactorManager, dispatcher, session ); } else { @@ -188,13 +188,13 @@ public class DefaultLifecycleExecutor { MavenProject currentProject = (MavenProject) projectIterator.next(); - executeTaskSegmentsForProject( segment, currentProject, reactorManager, dispatcher, session ); + executeTaskSegmentForProject( segment, currentProject, reactorManager, dispatcher, session ); } } } } - private void executeTaskSegmentsForProject( TaskSegment segment, + private void executeTaskSegmentForProject( TaskSegment segment, MavenProject project, ReactorManager reactorManager, EventDispatcher dispatcher, @@ -397,10 +397,7 @@ public class DefaultLifecycleExecutor List mojoBindings; try { - BuildPlan plan = buildPlanner.constructBuildPlan( - tasks, - project, - session ); + BuildPlan plan = buildPlanner.constructBuildPlan( tasks, project, session, false ); if ( getLogger().isDebugEnabled() ) { diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java index 79d094fc73..fbb00fe835 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; /** @@ -72,8 +73,7 @@ public class DefaultLifecycleBindingManager private PlexusContainer container; /** - * Retrieve the LifecycleBindings given by the lifecycle mapping component/file for the project's packaging. Any - * applicable mojo configuration will be injected into the LifecycleBindings from the POM. + * {@inheritDoc} */ public LifecycleBindings getBindingsForPackaging( final MavenProject project, final MavenSession session ) throws LifecycleLoaderException, LifecycleSpecificationException @@ -123,8 +123,7 @@ public class DefaultLifecycleBindingManager } /** - * Construct the LifecycleBindings for the default lifecycle mappings, including injection of configuration from the - * project into each MojoBinding, where appropriate. + * {@inheritDoc} */ public LifecycleBindings getDefaultBindings( final MavenProject project ) throws LifecycleSpecificationException { @@ -141,10 +140,9 @@ public class DefaultLifecycleBindingManager } /** - * Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within the POM itself. - * @param session + * {@inheritDoc} */ - public LifecycleBindings getProjectCustomBindings( final MavenProject project, final MavenSession session ) + public LifecycleBindings getProjectCustomBindings( final MavenProject project, final MavenSession session, Set unbindableMojos ) throws LifecycleLoaderException, LifecycleSpecificationException { LifecycleBindings bindings = new LifecycleBindings(); @@ -210,7 +208,7 @@ public class DefaultLifecycleBindingManager } catch ( PluginLoaderException e ) { - mojoBinding.setLateBound( true ); + unbindableMojos.add( mojoBinding ); String message = "Failed to load plugin descriptor for: " + plugin @@ -236,6 +234,8 @@ public class DefaultLifecycleBindingManager { logger.error( "Somehow, the PluginDescriptor for plugin: " + plugin.getKey() + " contains no mojos. This is highly irregular. Ignoring..." ); + + unbindableMojos.add( mojoBinding ); continue; } @@ -267,14 +267,15 @@ public class DefaultLifecycleBindingManager } else { - logger.debug( "Skipping addition to build-plan for goal: " + logger.warn( "\n\nSkipping addition to build-plan for goal: " + goal + " in execution: " + execution.getId() + " of plugin: " + plugin.getKey() - + " because no phase information was available (either through the mojo descriptor, which is currently missing, or in the POM itself)." ); + + " because no phase information was available (either through the mojo descriptor, which is currently missing, or in the POM itself).\n\n" ); + unbindableMojos.add( mojoBinding ); continue; } } @@ -294,8 +295,7 @@ public class DefaultLifecycleBindingManager } /** - * Construct the LifecycleBindings that constitute the mojos mapped to the lifecycles by an overlay specified in a - * plugin. Inject mojo configuration from the POM into all appropriate MojoBinding instances. + * {@inheritDoc} */ public LifecycleBindings getPluginLifecycleOverlay( final PluginDescriptor pluginDescriptor, final String lifecycleId, final MavenProject project ) @@ -417,15 +417,7 @@ public class DefaultLifecycleBindingManager } /** - * Retrieve the list of MojoBinding instances that correspond to the reports configured for the specified project. - * Inject all appropriate configuration from the POM for each MojoBinding, using the following precedence rules: - *
- *
    - *
  1. report-set-level configuration
  2. - *
  3. reporting-level configuration
  4. - *
  5. execution-level configuration
  6. - *
  7. plugin-level configuration
  8. - *
+ * {@inheritDoc} */ public List getReportBindings( final MavenProject project, final MavenSession session ) throws LifecycleLoaderException, LifecycleSpecificationException @@ -601,4 +593,49 @@ public class DefaultLifecycleBindingManager container = (PlexusContainer) ctx.get( PlexusConstants.PLEXUS_KEY ); } + /** + * {@inheritDoc} + */ + public void resolveUnbindableMojos( final Set unbindableMojos, + final MavenProject project, + final MavenSession session, + final LifecycleBindings lifecycleBindings ) + throws LifecycleSpecificationException + { + for ( Iterator it = unbindableMojos.iterator(); it.hasNext(); ) + { + MojoBinding binding = (MojoBinding) it.next(); + PluginDescriptor pluginDescriptor; + try + { + pluginDescriptor = pluginLoader.loadPlugin( binding, project, session ); + } + catch ( PluginLoaderException e ) + { + String message = "Failed to load plugin descriptor for: " + + MojoBindingUtils.toString( binding ) + + ". Cannot discover it's default phase, specified in its plugin descriptor."; + + throw new LifecycleSpecificationException( message, e ); + } + + MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( binding.getGoal() ); + if ( mojoDescriptor == null ) + { + throw new LifecycleSpecificationException( "Cannot find mojo descriptor for goal: " + binding.getGoal() + " in plugin: " + pluginDescriptor.getPluginLookupKey() ); + } + + String phase = mojoDescriptor.getPhase(); + if ( phase == null ) + { + throw new LifecycleSpecificationException( + "Mojo descriptor: " + + mojoDescriptor.getFullGoalName() + + " doesn't have a default lifecycle phase. Please specify a for this goal in your POM." ); + } + + LifecycleUtils.addMojoBinding( phase, binding, lifecycleBindings ); + } + } + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java index 1d867b499b..88cad3a5db 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/binding/LifecycleBindingManager.java @@ -4,10 +4,13 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.LifecycleLoaderException; import org.apache.maven.lifecycle.LifecycleSpecificationException; import org.apache.maven.lifecycle.model.LifecycleBindings; +import org.apache.maven.lifecycle.model.MojoBinding; +import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; import java.util.List; +import java.util.Set; /** * Responsible for the gross construction of LifecycleBindings, or mappings of MojoBinding instances to different parts @@ -39,7 +42,7 @@ public interface LifecycleBindingManager /** * Construct the LifecycleBindings that constitute the extra mojos bound to the lifecycle within the POM itself. */ - LifecycleBindings getProjectCustomBindings( MavenProject project, MavenSession session ) + LifecycleBindings getProjectCustomBindings( MavenProject project, MavenSession session, Set unresolvableBindings ) throws LifecycleLoaderException, LifecycleSpecificationException; /** @@ -63,4 +66,20 @@ public interface LifecycleBindingManager */ List getReportBindings( MavenProject project, MavenSession session ) throws LifecycleLoaderException, LifecycleSpecificationException; + /** + * Go through the set of unbindable mojos provided (these are {@link MojoBinding} instancess coming + * from the project as custom bindings for which we failed to determine a phase + * to bind them during {@link LifecycleBindingManager#getProjectCustomBindings(MavenProject, MavenSession, Set)}). + * For each {@link MojoBinding}, attempt to resolve it again, and if successful, + * extract the default phase name from the {@link MojoDescriptor}. + * + * @throws LifecycleSpecificationException In case the plugin cannot be resolved, the plugin doesn't contain the specified mojo, + * or the mojo doesn't have a default phase. + */ + void resolveUnbindableMojos( final Set unbindableMojos, + final MavenProject project, + final MavenSession session, + final LifecycleBindings lifecycleBindings ) + throws LifecycleSpecificationException; + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java index b4e4ef4edd..2b4a45173c 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlan.java @@ -38,17 +38,20 @@ public class BuildPlan private boolean includingReports = false; + private Set unbindableMojos; + public BuildPlan( final LifecycleBindings packaging, final LifecycleBindings projectBindings, - final LifecycleBindings defaults, final List tasks ) + final LifecycleBindings defaults, final Set unbindableMojos, final List tasks ) throws LifecycleSpecificationException, LifecycleLoaderException { - this( LifecycleUtils.mergeBindings( packaging, projectBindings, defaults, true, false ), tasks ); + this( LifecycleUtils.mergeBindings( packaging, projectBindings, defaults, true, false ), unbindableMojos, tasks ); } - public BuildPlan( final LifecycleBindings bindings, final List tasks ) + public BuildPlan( final LifecycleBindings bindings, final Set unbindableMojos, final List tasks ) throws LifecycleSpecificationException, LifecycleLoaderException { this.bindings = bindings; + this.unbindableMojos = unbindableMojos == null ? null : new HashSet( unbindableMojos ); this.tasks = tasks; forkedDirectInvocations = new HashMap(); forkedPhases = new HashMap(); @@ -56,9 +59,10 @@ public class BuildPlan } private BuildPlan( final LifecycleBindings bindings, final Map forkedDirectInvocations, final Map forkedPhases, - final Map directInvocationBindings, final Set fullyResolvedMojoBindings, final List tasks, - boolean includingReports ) + final Map directInvocationBindings, final Set fullyResolvedMojoBindings, final Set unbindableMojos, + final List tasks, boolean includingReports ) { + this.unbindableMojos = unbindableMojos == null ? null : new HashSet( unbindableMojos ); this.bindings = LifecycleUtils.cloneBindings( bindings ); this.forkedDirectInvocations = new HashMap( forkedDirectInvocations ); this.forkedPhases = new HashMap( forkedPhases ); @@ -78,6 +82,26 @@ public class BuildPlan return includingReports; } + public boolean hasUnbindableMojos() + { + return unbindableMojos != null && !unbindableMojos.isEmpty(); + } + + public Set getUnbindableMojos() + { + return unbindableMojos; + } + + public void clearUnbindableMojos() + { + unbindableMojos = null; + } + + public void addUnbindableMojo( MojoBinding binding ) + { + unbindableMojos.add( binding ); + } + public boolean isFullyResolved( final MojoBinding mojoBinding ) { String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false ); @@ -176,7 +200,7 @@ public class BuildPlan public BuildPlan copy( final List newTasks ) { - return new BuildPlan( bindings, forkedDirectInvocations, forkedPhases, directInvocationBindings, fullyResolvedBindings, newTasks, includingReports ); + return new BuildPlan( bindings, forkedDirectInvocations, forkedPhases, directInvocationBindings, fullyResolvedBindings, unbindableMojos, newTasks, includingReports ); } public void resetExecutionProgress() @@ -227,7 +251,6 @@ public class BuildPlan String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false ); if ( !executionStack.contains( key ) ) { - addResolverIfLateBound( mojoBinding, plan ); plan.addAll( findForkedBindings( mojoBinding, executionStack ) ); } } @@ -238,7 +261,6 @@ public class BuildPlan String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, false ); if ( !executionStack.contains( key ) ) { - addResolverIfLateBound( mojoBinding, plan ); plan.addAll( findForkedBindings( mojoBinding, executionStack ) ); } } @@ -247,15 +269,6 @@ public class BuildPlan return plan; } - private void addResolverIfLateBound( final MojoBinding mojoBinding, final List plan ) - { - if ( mojoBinding.isLateBound() ) - { - MojoBinding resolveBinding = StateManagementUtils.createResolveLateBoundMojoBinding( mojoBinding ); - plan.add( resolveBinding ); - } - } - private List findForkedBindings( final MojoBinding mojoBinding, final Stack executionStack ) throws NoSuchPhaseException { @@ -294,7 +307,6 @@ public class BuildPlan continue; } - addResolverIfLateBound( invocation, forkedBindings ); forkedBindings.addAll( findForkedBindings( invocation, executionStack ) ); } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java index 5b1aa76f40..3eb666ed70 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/BuildPlanner.java @@ -24,7 +24,8 @@ public interface BuildPlanner */ BuildPlan constructBuildPlan( List tasks, MavenProject project, - MavenSession session ) + MavenSession session, + boolean allowUnbindableMojos ) throws LifecycleLoaderException, LifecycleSpecificationException, LifecyclePlannerException; void constructInitialProjectBuildPlans( MavenSession session ) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java index 5d5e810d2c..95573ceb17 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java @@ -18,9 +18,11 @@ import org.codehaus.plexus.logging.LogEnabled; import org.codehaus.plexus.logging.Logger; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.Stack; /** @@ -62,7 +64,7 @@ public class DefaultBuildPlanner BuildPlan plan = session.getBuildPlan( project ); if ( plan == null ) { - plan = constructBuildPlan( Collections.EMPTY_LIST, project, session ); + plan = constructBuildPlan( Collections.EMPTY_LIST, project, session, true ); session.setBuildPlan( project, plan ); } @@ -73,13 +75,15 @@ public class DefaultBuildPlanner /** * Orchestrates construction of the build plan which will be used by the user of LifecycleExecutor. */ - public BuildPlan constructBuildPlan( final List tasks, - final MavenProject project, - final MavenSession session ) + public BuildPlan constructBuildPlan( List tasks, + MavenProject project, + MavenSession session, + boolean allowUnbindableMojos ) throws LifecycleLoaderException, LifecycleSpecificationException, LifecyclePlannerException { BuildPlan plan = session.getBuildPlan( project ); + boolean pluginResolutionAttempted = false; if ( plan != null ) { plan = plan.copy( tasks ); @@ -87,20 +91,31 @@ public class DefaultBuildPlanner else { LifecycleBindings defaultBindings = lifecycleBindingManager.getDefaultBindings( project ); + LifecycleBindings packagingBindings = lifecycleBindingManager.getBindingsForPackaging( project, session ); - LifecycleBindings projectBindings = lifecycleBindingManager.getProjectCustomBindings( project, - session ); - plan = new BuildPlan( packagingBindings, projectBindings, defaultBindings, tasks ); + Set unbindableMojos = new HashSet(); + LifecycleBindings projectBindings = lifecycleBindingManager.getProjectCustomBindings( project, + session, + unbindableMojos ); + + plan = new BuildPlan( packagingBindings, projectBindings, defaultBindings, unbindableMojos, tasks ); + pluginResolutionAttempted = true; + } + + if ( ( !pluginResolutionAttempted || !allowUnbindableMojos ) && plan.hasUnbindableMojos() ) + { + lifecycleBindingManager.resolveUnbindableMojos( plan.getUnbindableMojos(), project, session, plan.getLifecycleBindings() ); + plan.clearUnbindableMojos(); } // initialize/resolve any direct-invocation tasks, if possible. initializeDirectInvocations( plan, project, session ); // Inject forked lifecycles as plan modifiers for each mojo that has @execute in it. - addForkedLifecycleModifiers( plan, project, session, new LinkedList() ); - addReportingLifecycleModifiers( plan, project, session, new LinkedList() ); + addForkedLifecycleModifiers( plan, project, session, new LinkedList(), allowUnbindableMojos ); + addReportingLifecycleModifiers( plan, project, session, new LinkedList(), allowUnbindableMojos ); plan.markFullyResolved(); @@ -147,8 +162,9 @@ public class DefaultBuildPlanner */ private void addForkedLifecycleModifiers( final BuildPlan plan, final MavenProject project, - MavenSession session, - LinkedList callStack ) + final MavenSession session, + LinkedList callStack, + final boolean allowUnbindableMojos ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { List planBindings = plan.renderExecutionPlan( new Stack() ); @@ -160,7 +176,7 @@ public class DefaultBuildPlanner if ( !plan.isFullyResolved( mojoBinding ) ) { - findForkModifiers( mojoBinding, plan, project, session, callStack ); + findForkModifiers( mojoBinding, plan, project, session, callStack, allowUnbindableMojos ); } } } @@ -169,13 +185,15 @@ public class DefaultBuildPlanner final BuildPlan plan, final MavenProject project, MavenSession session, - LinkedList callStack ) + LinkedList callStack, + final boolean allowUnbindableMojos ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { PluginDescriptor pluginDescriptor = loadPluginDescriptor( mojoBinding, plan, project, - session ); + session, + allowUnbindableMojos ); if ( pluginDescriptor == null ) { @@ -190,20 +208,19 @@ public class DefaultBuildPlanner + pluginDescriptor.getId() + "." ); } - findForkModifiers( mojoBinding, pluginDescriptor, plan, project, session, false, callStack ); + findForkModifiers( mojoBinding, pluginDescriptor, plan, project, session, callStack, false, allowUnbindableMojos ); } /** * Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and orchestrates the * process of injecting any modifiers that are necessary to accommodate mojos that require access to the project's * configured reports. - * @param callStack - * @param session */ private void addReportingLifecycleModifiers( final BuildPlan plan, final MavenProject project, - MavenSession session, - LinkedList callStack ) + final MavenSession session, + LinkedList callStack, + final boolean allowUnbindableMojos ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { if ( plan.isIncludingReports() ) @@ -228,7 +245,8 @@ public class DefaultBuildPlanner PluginDescriptor pluginDescriptor = loadPluginDescriptor( mojoBinding, plan, project, - session ); + session, + allowUnbindableMojos ); if ( pluginDescriptor == null ) { @@ -265,7 +283,8 @@ public class DefaultBuildPlanner PluginDescriptor pd = loadPluginDescriptor( reportBinding, plan, project, - session ); + session, + allowUnbindableMojos ); if ( pd != null ) { @@ -274,8 +293,9 @@ public class DefaultBuildPlanner plan, project, session, + callStack, true, - callStack ); + allowUnbindableMojos ); } } } @@ -292,7 +312,9 @@ public class DefaultBuildPlanner private PluginDescriptor loadPluginDescriptor( final MojoBinding mojoBinding, final BuildPlan plan, final MavenProject project, - final MavenSession session ) + final MavenSession session, + final boolean allowUnbindableMojos ) + throws LifecyclePlannerException { PluginDescriptor pluginDescriptor = null; try @@ -301,20 +323,27 @@ public class DefaultBuildPlanner } catch ( PluginLoaderException e ) { - String message = "Failed to load plugin: " - + MojoBindingUtils.createPluginKey( mojoBinding ) - + ". Adding to late-bound plugins list.\nReason: " + e.getMessage(); - - if ( logger.isDebugEnabled() ) + if ( allowUnbindableMojos ) { - logger.debug( message, e ); + String message = "Failed to load plugin: " + + MojoBindingUtils.createPluginKey( mojoBinding ) + + ". Adding to late-bound plugins list.\nReason: " + e.getMessage(); + + if ( logger.isDebugEnabled() ) + { + logger.debug( message, e ); + } + else + { + logger.warn( message ); + } + + plan.addUnbindableMojo( mojoBinding ); } else { - logger.warn( message ); + throw new LifecyclePlannerException( "Failed to resolve plugin for mojo binding: " + MojoBindingUtils.toString( mojoBinding ), e ); } - - mojoBinding.setLateBound( true ); } return pluginDescriptor; @@ -330,8 +359,9 @@ public class DefaultBuildPlanner final BuildPlan plan, final MavenProject project, final MavenSession session, + LinkedList callStack, final boolean includeReportConfig, - LinkedList callStack ) + final boolean allowUnbindableMojos ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { String referencingGoal = mojoBinding.getGoal(); @@ -360,8 +390,9 @@ public class DefaultBuildPlanner plan, project, session, + callStack, includeReportConfig, - callStack ); + allowUnbindableMojos ); } } @@ -380,8 +411,9 @@ public class DefaultBuildPlanner final BuildPlan plan, final MavenProject project, final MavenSession session, + LinkedList callStack, final boolean includeReportConfig, - LinkedList callStack ) + final boolean allowUnbindableMojos ) throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException { callStack.addFirst( mojoBinding ); @@ -429,7 +461,7 @@ public class DefaultBuildPlanner plan.addForkedExecution( mojoBinding, clonedPlan ); - addForkedLifecycleModifiers( clonedPlan, project, session, callStack ); + addForkedLifecycleModifiers( clonedPlan, project, session, callStack, allowUnbindableMojos ); } finally { diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java index 73dcf890bf..a08489eef3 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java @@ -28,6 +28,7 @@ import org.easymock.MockControl; import java.io.File; import java.net.URL; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Properties; @@ -203,7 +204,7 @@ public class DefaultLifecycleBindingManagerTest MavenProject project = new MavenProject( model ); - LifecycleBindings lifecycleBindings = mgr.getProjectCustomBindings( project, null ); + LifecycleBindings lifecycleBindings = mgr.getProjectCustomBindings( project, null, new HashSet() ); List bindings = lifecycleBindings.getBuildBinding().getValidate().getBindings(); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java index c113a8625e..2007753955 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java @@ -10,6 +10,7 @@ import org.apache.maven.lifecycle.statemgmt.StateManagementUtils; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Stack; @@ -64,11 +65,12 @@ public class BuildPlanTest check.add( StateManagementUtils.createClearForkedExecutionMojoBinding() ); - BuildPlan plan = new BuildPlan( new LifecycleBindings(), tasks ); + BuildPlan plan = new BuildPlan( new LifecycleBindings(), new HashSet(), tasks ); plan.addDirectInvocationBinding( "eclipse:eclipse", eclipseBinding ); plan.addForkedExecution( eclipseBinding, new BuildPlan( bindings, + new HashSet(), Collections.singletonList( "generate-sources" ) ) ); List executionPlan = plan.renderExecutionPlan( new Stack() ); @@ -120,7 +122,7 @@ public class BuildPlanTest List tasks = Collections.singletonList( "package" ); - BuildPlan plan = new BuildPlan( bindings, tasks ); + BuildPlan plan = new BuildPlan( bindings, new HashSet(), tasks ); plan.addForkedExecution( assemblyBinding, plan.copy( "package" ) ); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/plan/DefaultBuildPlannerTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/plan/DefaultBuildPlannerTest.java index 4050a36968..d4173fc472 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/plan/DefaultBuildPlannerTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/plan/DefaultBuildPlannerTest.java @@ -88,7 +88,8 @@ public class DefaultBuildPlannerTest BuildPlan plan = buildPlanner.constructBuildPlan( Collections.singletonList( "package" ), project, - session ); + session, + false ); List rendered = plan.renderExecutionPlan( new Stack() ); @@ -154,7 +155,8 @@ public class DefaultBuildPlannerTest BuildPlan plan = buildPlanner.constructBuildPlan( Collections.singletonList( "deploy" ), project, - session ); + session, + false ); List rendered = plan.renderExecutionPlan( new Stack() ); diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java index 61da51695f..4bc40ad628 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java @@ -532,6 +532,14 @@ public class MavenEmbedder public BuildPlan getBuildPlan( List goals, MavenProject project ) throws MavenEmbedderException + { + return getBuildPlan( goals, project, false ); + } + + public BuildPlan getBuildPlan( List goals, + MavenProject project, + boolean allowUnbindableMojos ) + throws MavenEmbedderException { MavenExecutionRequest req = new DefaultMavenExecutionRequest( request ); req.setGoals( goals ); @@ -559,7 +567,7 @@ public class MavenEmbedder try { - return buildPlanner.constructBuildPlan( goals, project, session ); + return buildPlanner.constructBuildPlan( goals, project, session, allowUnbindableMojos ); } catch ( LifecycleException e ) { diff --git a/maven-embedder/src/test/java/org/apache/maven/error/ErrorReporterPointcutTest.java b/maven-embedder/src/test/java/org/apache/maven/error/ErrorReporterPointcutTest.java index 41c080efad..dac1447ff8 100644 --- a/maven-embedder/src/test/java/org/apache/maven/error/ErrorReporterPointcutTest.java +++ b/maven-embedder/src/test/java/org/apache/maven/error/ErrorReporterPointcutTest.java @@ -152,12 +152,6 @@ public class ErrorReporterPointcutTest return method; } - private File prepareProjectDir() - throws IOException - { - return prepareProjectDir( "nothing" ); - } - private File prepareProjectDir( String basename ) throws IOException { @@ -494,7 +488,7 @@ public class ErrorReporterPointcutTest .setShowErrors( true ) .setErrorReporter( reporter ) .setGoals( Arrays.asList( new String[] { - "initialize" + "org.apache.maven.errortest:err-loading-plugin-maven-plugin:1:test" } ) ); maven.execute( request ); @@ -1355,31 +1349,36 @@ public class ErrorReporterPointcutTest reporterCtl.verify(); } - public void testReportInvalidRepositoryWhileGettingRepositoriesFromProfiles() - throws IOException - { - File projectDir = prepareProjectDir( "bad-profile-repo" ); - - reporter.reportInvalidRepositoryWhileGettingRepositoriesFromProfiles( null, - null, - null, - null ); - reporterCtl.setMatcher( MockControl.ALWAYS_MATCHER ); - reporterCtl.setVoidCallable(); - - reporterCtl.replay(); - - MavenExecutionRequest request = new DefaultMavenExecutionRequest().setBaseDirectory( projectDir ) - .setShowErrors( true ) - .setErrorReporter( reporter ) - .setGoals( Arrays.asList( new String[] { - "initialize" - } ) ); - - maven.execute( request ); - - reporterCtl.verify(); - } + // FIXME: Something keeps flip-flopping about this test, between the two reporter methods below...need to revisit this pronto. +// public void testReportErrorCreatingArtifactRepository_fromProfilesXml() +// throws IOException +// { +// File projectDir = prepareProjectDir( "bad-profile-repo" ); +// +// reporter.reportInvalidRepositoryWhileGettingRepositoriesFromProfiles( null, null, null, null ); +// reporterCtl.setMatcher( MockControl.ALWAYS_MATCHER ); +//// reporterCtl.setVoidCallable( MockControl.ZERO_OR_MORE ); +// +//// reporter.reportErrorCreatingArtifactRepository( null, null, null, null ); +//// reporterCtl.setMatcher( MockControl.ALWAYS_MATCHER ); +// reporterCtl.setVoidCallable(); +// +// reporterCtl.replay(); +// +// MavenExecutionRequest request = new DefaultMavenExecutionRequest().setBaseDirectory( projectDir ) +// .setLoggingLevel( Logger.LEVEL_DEBUG ) +// .setShowErrors( true ) +// .setErrorReporter( reporter ) +// .setGoals( Arrays.asList( new String[] { +// "initialize" +// } ) ); +// +// MavenExecutionResult result = maven.execute( request ); +// +// reportExceptions( result, projectDir, false ); +// +// reporterCtl.verify(); +// } public void testReportParentPomArtifactNotFound() throws IOException diff --git a/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java b/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java index de8ee0ff51..4415f4de78 100644 --- a/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java +++ b/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java @@ -200,6 +200,7 @@ public class LifecycleUtils Phase phase = (Phase) phases.get( idx ); phase.addBinding( mojoBinding ); + mojoBinding.setLifecycleInfo( phase ); } public static void addMojoBinding( final String phaseName, final MojoBinding mojo, final LifecycleBindings bindings ) diff --git a/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo b/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo index debae7c02b..c257a34acd 100644 --- a/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo +++ b/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo @@ -678,25 +678,6 @@ this.originDescription = originDescription; } - private boolean lateBound = false; - - /** - * Mark this mojo binding as late-bound, meaning the plugin for this mojo - * could not be resolved when it was included in a build plan (the class - * responsible for calculating the ordered list of mojos to execute for a build). - * This flag should result in Maven injecting an internal step into the build - * just ahead of this mojo's execution, to resolve the plugin it refers to. - */ - public boolean isLateBound() - { - return lateBound; - } - - public void setLateBound( boolean lateBound ) - { - this.lateBound = lateBound; - } - private Phase phase; /** diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java index 01798b0749..5c08894f35 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineageBuilder.java @@ -367,6 +367,7 @@ public class DefaultModelLineageBuilder result = projectWorkspace.getModelAndFile( parentPomFile ); if ( result != null && !parentModelMatches( modelParent, result.getModel() ) ) { + parentPomFile = null; result = null; } } @@ -386,10 +387,17 @@ public class DefaultModelLineageBuilder getLogger().debug( "Allowing parent-model resolution to proceed for: " + key + " (child is: " + model.getId() + ")" ); - if ( parentPomFile != null && parentPomFile.exists() ) + if ( parentPomFile != null ) { - Model parentModel = readModel( parentPomFile ); - if ( !parentModelMatches( modelParent, parentModel ) ) + if ( parentPomFile.exists() ) + { + Model parentModel = readModel( parentPomFile ); + if ( !parentModelMatches( modelParent, parentModel ) ) + { + parentPomFile = null; + } + } + else { parentPomFile = null; } @@ -480,7 +488,7 @@ public class DefaultModelLineageBuilder boolean versionsMatch = ( parentModel.getVersion() == null ) || parentModel.getVersion().equals( modelParent.getVersion() ); - if ( groupsMatch && !versionsMatch + if ( groupsMatch && versionsMatch && parentModel.getArtifactId().equals( modelParent.getArtifactId() ) ) { return true; diff --git a/maven-project/src/test/java/org/apache/maven/project/workspace/ModelAndFileCachingTest.java b/maven-project/src/test/java/org/apache/maven/project/workspace/ModelAndFileCachingTest.java index 26232c392f..5da0042441 100644 --- a/maven-project/src/test/java/org/apache/maven/project/workspace/ModelAndFileCachingTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/workspace/ModelAndFileCachingTest.java @@ -136,7 +136,7 @@ public class ModelAndFileCachingTest new DefaultProjectBuilderConfiguration().setLocalRepository( localRepo ).setGlobalProfileManager( profileManager ), Collections.EMPTY_LIST, false, - false ); + true ); assertEquals( parentPomFile.getCanonicalPath(), lineage.getDeepestAncestorFile() .getCanonicalPath() );