[MNG-4651] Re-added missing methods for 3.x site plugin

Also clarified role of LifecylceExecutor as a 'facade providing lifecycle services'

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@939028 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Kristian Rosenvold 2010-04-28 17:51:31 +00:00
parent dc09df4b99
commit 1248bd1c1f
9 changed files with 297 additions and 175 deletions

View File

@ -39,6 +39,7 @@ import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ProjectDependencyGraph;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
import org.apache.maven.lifecycle.internal.LifecycleStarter;
import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.building.ModelProblemUtils;
import org.apache.maven.model.building.ModelSource;
@ -74,8 +75,9 @@ public class DefaultMaven
@Requirement
protected ProjectBuilder projectBuilder;
@Requirement
protected LifecycleExecutor lifecycleExecutor;
private LifecycleStarter lifecycleStarter;
@Requirement
protected PlexusContainer container;
@ -243,7 +245,7 @@ public class DefaultMaven
return result;
}
lifecycleExecutor.execute( session );
lifecycleStarter.execute( session );
validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );

View File

@ -14,26 +14,19 @@
*/
package org.apache.maven.lifecycle;
import org.apache.maven.execution.*;
import org.apache.maven.lifecycle.internal.BuildListCalculator;
import org.apache.maven.lifecycle.internal.ConcurrencyDependencyGraph;
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
import org.apache.maven.lifecycle.internal.LifecycleDebugLogger;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.internal.DependencyContext;
import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
import org.apache.maven.lifecycle.internal.LifecycleModuleBuilder;
import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculatorImpl;
import org.apache.maven.lifecycle.internal.LifecycleStarter;
import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
import org.apache.maven.lifecycle.internal.LifecycleThreadedBuilder;
import org.apache.maven.lifecycle.internal.LifecycleWeaveBuilder;
import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
import org.apache.maven.lifecycle.internal.ProjectBuildList;
import org.apache.maven.lifecycle.internal.MojoExecutor;
import org.apache.maven.lifecycle.internal.ProjectIndex;
import org.apache.maven.lifecycle.internal.ProjectSegment;
import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
import org.apache.maven.lifecycle.internal.ReactorContext;
import org.apache.maven.lifecycle.internal.TaskSegment;
import org.apache.maven.lifecycle.internal.ThreadConfigurationService;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginManagerException;
@ -45,16 +38,18 @@ import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.TreeSet;
/**
* A facade that provides lifecycle services to components outside maven core.
*
* Note that this component is not normally used from within core itself.
*
* @author Jason van Zyl
* @author Benjamin Bentmann
* @author Kristian Rosenvold
@ -64,33 +59,12 @@ public class DefaultLifecycleExecutor
implements LifecycleExecutor
{
@Requirement
private ExecutionEventCatapult eventCatapult;
@Requirement
private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer;
@Requirement
private DefaultLifecycles defaultLifeCycles;
@Requirement
private Logger logger;
@Requirement
private LifecycleModuleBuilder lifecycleModuleBuilder;
@Requirement
private LifecycleWeaveBuilder lifeCycleWeaveBuilder;
@Requirement
private LifecycleThreadedBuilder lifecycleThreadedBuilder;
@Requirement
private BuildListCalculator buildListCalculator;
@Requirement
private LifecycleDebugLogger lifecycleDebugLogger;
@Requirement
private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
@ -98,140 +72,17 @@ public class DefaultLifecycleExecutor
private LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator;
@Requirement
private ThreadConfigurationService threadConfigService;
private MojoExecutor mojoExecutor;
@Requirement
private LifecycleStarter lifecycleStarter;
public DefaultLifecycleExecutor()
{
}
public void execute( MavenSession session )
{
eventCatapult.fire( ExecutionEvent.Type.SessionStarted, session, null );
MavenExecutionResult result = session.getResult();
try
{
if ( !session.isUsingPOMsFromFilesystem() && lifecycleTaskSegmentCalculator.requiresProject( session ) )
{
throw new MissingProjectException( "The goal you specified requires a project to execute" +
" but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")." +
" Please verify you invoked Maven from the correct directory." );
}
final MavenExecutionRequest executionRequest = session.getRequest();
boolean isThreaded = executionRequest.isThreadConfigurationPresent();
session.setParallel( isThreaded );
List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
ProjectBuildList projectBuilds = buildListCalculator.calculateProjectBuilds( session, taskSegments );
if ( projectBuilds.isEmpty() )
{
throw new NoGoalSpecifiedException( "No goals have been specified for this build." +
" You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or" +
" <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>." +
" Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + "." );
}
ProjectIndex projectIndex = new ProjectIndex( session.getProjects() );
if ( logger.isDebugEnabled() )
{
lifecycleDebugLogger.debugReactorPlan( projectBuilds );
}
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
ReactorContext callableContext =
new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus );
if ( isThreaded )
{
ExecutorService executor = threadConfigService.getExecutorService( executionRequest.getThreadCount(),
executionRequest.isPerCoreThreadCount(),
session.getProjects().size() );
try
{
final boolean isWeaveMode = LifecycleWeaveBuilder.isWeaveMode( executionRequest );
if ( isWeaveMode )
{
lifecycleDebugLogger.logWeavePlan( session );
CompletionService<ProjectSegment> service =
new ExecutorCompletionService<ProjectSegment>( executor );
lifeCycleWeaveBuilder.build( projectBuilds, callableContext, taskSegments, session, service,
reactorBuildStatus );
}
else
{
ConcurrencyDependencyGraph analyzer =
new ConcurrencyDependencyGraph( projectBuilds, session.getProjectDependencyGraph() );
CompletionService<ProjectSegment> service =
new ExecutorCompletionService<ProjectSegment>( executor );
lifecycleThreadedBuilder.build( session, callableContext, projectBuilds, taskSegments, analyzer,
service );
}
}
finally
{
executor.shutdown();
}
}
else
{
singleThreadedBuild( session, callableContext, projectBuilds, taskSegments, reactorBuildStatus );
}
}
catch (
Exception e
)
{
result.addException( e );
}
eventCatapult.fire( ExecutionEvent.Type.SessionEnded, session, null );
lifecycleStarter.execute( session );
}
private void singleThreadedBuild( MavenSession session, ReactorContext callableContext,
ProjectBuildList projectBuilds, List<TaskSegment> taskSegments,
ReactorBuildStatus reactorBuildStatus )
{
for ( TaskSegment taskSegment : taskSegments )
{
for ( ProjectSegment projectBuild : projectBuilds.getByTaskSegment( taskSegment ) )
{
try
{
lifecycleModuleBuilder.buildProject( session, callableContext, projectBuild.getProject(),
taskSegment );
if ( reactorBuildStatus.isHalted() )
{
break;
}
}
catch ( Exception e )
{
break; // Why are we just ignoring this exception? Are exceptions are being used for flow control
}
}
}
}
/**
* * CRUFT GOES BELOW HERE ***
*/
@Requirement
private MojoDescriptorCreator mojoDescriptorCreator;
@ -245,6 +96,7 @@ public class DefaultLifecycleExecutor
// from the plugin.xml inside a plugin.
//
// TODO: This whole method could probably removed by injecting lifeCyclePluginAnalyzer straight into client site.
// TODO: But for some reason the whole plexus appcontext refuses to start when I try this.
public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
{
@ -295,4 +147,34 @@ public class DefaultLifecycleExecutor
mergedSegment.getTasks() );
}
// Site 3.x
public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
{
lifecycleExecutionPlanCalculator.calculateForkedExecutions( mojoExecution, session );
}
// Site 3.x
public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws LifecycleExecutionException
{
Set<String> requiredDependencyResolutionScopes = new TreeSet<String>();
Set<String> requiredDependencyCollectionScopes = new TreeSet<String>();
// Ok, so this method could probably have a better location.
LifecycleExecutionPlanCalculatorImpl.collectDependencyRequirements( requiredDependencyResolutionScopes,
requiredDependencyCollectionScopes,
mojoExecution );
final DependencyContext context =
new DependencyContext( requiredDependencyCollectionScopes, requiredDependencyResolutionScopes,
mojoExecution.getMojoDescriptor().isAggregator() );
mojoExecutor.executeForkedExecutions( mojoExecution, session, new ProjectIndex( session.getProjects() ),
context );
return Collections.emptyList();
}
}

View File

@ -19,11 +19,10 @@ package org.apache.maven.lifecycle;
* under the License.
*/
import java.util.Set;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginManagerException;
@ -31,10 +30,18 @@ import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import java.util.List;
import java.util.Set;
/**
* A facade that provides lifecycle services to components outside maven core.
*
*
* @author Jason van Zyl
*/
@SuppressWarnings( { "UnusedDeclaration" } )
public interface LifecycleExecutor
{
@ -51,6 +58,7 @@ public interface LifecycleExecutor
// We need to know the specific version so that we can lookup the right version of the plugin descriptor
// which tells us what the default configuration is.
//
/**
* @return The plugins bound to the lifecycles of the specified packaging or {@code null} if the packaging is
* unknown.
@ -65,4 +73,14 @@ public interface LifecycleExecutor
void execute( MavenSession session );
public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws LifecycleExecutionException;
}

View File

@ -44,8 +44,8 @@ public class DependencyContext
private volatile int lastDependencyArtifactCount;
private DependencyContext( Collection<String> scopesToCollect, Collection<String> scopesToResolve,
boolean aggregating )
public DependencyContext( Collection<String> scopesToCollect, Collection<String> scopesToResolve,
boolean aggregating )
{
this.scopesToCollect = scopesToCollect;
this.scopesToResolve = scopesToResolve;

View File

@ -30,7 +30,6 @@ import java.util.List;
* @author Benjamin Bentmann
* @author Kristian Rosenvold (extract interface only)
* <p/>
* NOTE: interface is not part of any public api and can be changed or deleted without prior notice.
*/
public interface LifecycleExecutionPlanCalculator
{
@ -39,4 +38,11 @@ public interface LifecycleExecutionPlanCalculator
PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException;
public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
}

View File

@ -200,7 +200,7 @@ public class LifecycleExecutionPlanCalculatorImpl
return mojoExecutions;
}
private static void collectDependencyRequirements( Collection<String> requiredDependencyResolutionScopes,
public static void collectDependencyRequirements( Collection<String> requiredDependencyResolutionScopes,
Collection<String> requiredDependencyCollectionScopes,
MojoExecution mojoExecution )
{
@ -476,6 +476,16 @@ public class LifecycleExecutionPlanCalculatorImpl
return MojoDescriptorCreator.convert( mojoDescriptor );
}
public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
{
calculateForkedExecutions( mojoExecution, session, session.getCurrentProject(), new HashSet<MojoDescriptor>() );
}
private void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session, MavenProject project,
Collection<MojoDescriptor> alreadyForkedExecutions )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,

View File

@ -0,0 +1,196 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.maven.lifecycle.internal;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.DefaultLifecycles;
import org.apache.maven.lifecycle.MissingProjectException;
import org.apache.maven.lifecycle.NoGoalSpecifiedException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
/**
* Starts the build life cycle
* @author Jason van Zyl
* @author Benjamin Bentmann
* @author Kristian Rosenvold
*/
@Component( role = LifecycleStarter.class )
public class LifecycleStarter
{
@Requirement
private ExecutionEventCatapult eventCatapult;
@Requirement
private DefaultLifecycles defaultLifeCycles;
@Requirement
private Logger logger;
@Requirement
private LifecycleModuleBuilder lifecycleModuleBuilder;
@Requirement
private LifecycleWeaveBuilder lifeCycleWeaveBuilder;
@Requirement
private LifecycleThreadedBuilder lifecycleThreadedBuilder;
@Requirement
private BuildListCalculator buildListCalculator;
@Requirement
private LifecycleDebugLogger lifecycleDebugLogger;
@Requirement
private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
@Requirement
private ThreadConfigurationService threadConfigService;
public void execute( MavenSession session )
{
eventCatapult.fire( ExecutionEvent.Type.SessionStarted, session, null );
MavenExecutionResult result = session.getResult();
try
{
if ( !session.isUsingPOMsFromFilesystem() && lifecycleTaskSegmentCalculator.requiresProject( session ) )
{
throw new MissingProjectException( "The goal you specified requires a project to execute" +
" but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")." +
" Please verify you invoked Maven from the correct directory." );
}
final MavenExecutionRequest executionRequest = session.getRequest();
boolean isThreaded = executionRequest.isThreadConfigurationPresent();
session.setParallel( isThreaded );
List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
ProjectBuildList projectBuilds = buildListCalculator.calculateProjectBuilds( session, taskSegments );
if ( projectBuilds.isEmpty() )
{
throw new NoGoalSpecifiedException( "No goals have been specified for this build." +
" You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or" +
" <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>." +
" Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + "." );
}
ProjectIndex projectIndex = new ProjectIndex( session.getProjects() );
if ( logger.isDebugEnabled() )
{
lifecycleDebugLogger.debugReactorPlan( projectBuilds );
}
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
ReactorContext callableContext =
new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus );
if ( isThreaded )
{
ExecutorService executor = threadConfigService.getExecutorService( executionRequest.getThreadCount(),
executionRequest.isPerCoreThreadCount(),
session.getProjects().size() );
try
{
final boolean isWeaveMode = LifecycleWeaveBuilder.isWeaveMode( executionRequest );
if ( isWeaveMode )
{
lifecycleDebugLogger.logWeavePlan( session );
CompletionService<ProjectSegment> service =
new ExecutorCompletionService<ProjectSegment>( executor );
lifeCycleWeaveBuilder.build( projectBuilds, callableContext, taskSegments, session, service,
reactorBuildStatus );
}
else
{
ConcurrencyDependencyGraph analyzer =
new ConcurrencyDependencyGraph( projectBuilds, session.getProjectDependencyGraph() );
CompletionService<ProjectSegment> service =
new ExecutorCompletionService<ProjectSegment>( executor );
lifecycleThreadedBuilder.build( session, callableContext, projectBuilds, taskSegments, analyzer,
service );
}
}
finally
{
executor.shutdown();
}
}
else
{
singleThreadedBuild( session, callableContext, projectBuilds, taskSegments, reactorBuildStatus );
}
}
catch (
Exception e
)
{
result.addException( e );
}
eventCatapult.fire( ExecutionEvent.Type.SessionEnded, session, null );
}
private void singleThreadedBuild( MavenSession session, ReactorContext callableContext,
ProjectBuildList projectBuilds, List<TaskSegment> taskSegments,
ReactorBuildStatus reactorBuildStatus )
{
for ( TaskSegment taskSegment : taskSegments )
{
for ( ProjectSegment projectBuild : projectBuilds.getByTaskSegment( taskSegment ) )
{
try
{
lifecycleModuleBuilder.buildProject( session, callableContext, projectBuild.getProject(),
taskSegment );
if ( reactorBuildStatus.isHalted() )
{
break;
}
}
catch ( Exception e )
{
break; // Why are we just ignoring this exception? Are exceptions are being used for flow control
}
}
}
}
}

View File

@ -191,7 +191,7 @@ public class MojoExecutor
}
}
private List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session,
public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session,
ProjectIndex projectIndex, DependencyContext dependencyContext )
throws LifecycleExecutionException
{

View File

@ -103,6 +103,14 @@ public class LifecycleExecutionPlanCalculatorStub
return result;
}
public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
{
// Maybe do something ?
}
public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,