diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java index 1160e88a8d5b..9849fffea3c5 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java @@ -45,7 +45,7 @@ @Singleton public class DefaultLifecycles { - public static final String[] STANDARD_LIFECYCLES = { "default", "clean", "site", "wrapper" }; + public static final String[] STANDARD_LIFECYCLES = { "clean", "default", "site", "wrapper" }; private final Logger logger = LoggerFactory.getLogger( getClass() ); @@ -117,6 +117,9 @@ public Map getPhaseToLifecycleMap() return phaseToLifecycleMap; } + /** + * Returns an ordered list of lifecycles + */ public List getLifeCycles() { List lifecycleIds = Arrays.asList( STANDARD_LIFECYCLES ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java index 65843f853077..b0e3fa16c4ef 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java @@ -19,8 +19,6 @@ * under the License. */ -import java.util.ArrayList; -import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -110,7 +108,7 @@ public Set getPluginsBoundByDefaultToAllLifecycles( String packaging ) Map plugins = new LinkedHashMap<>(); - for ( Lifecycle lifecycle : getOrderedLifecycles() ) + for ( Lifecycle lifecycle : defaultLifeCycles.getLifeCycles() ) { org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration = lifecycleMappingForPackaging.getLifecycles().get( lifecycle.getId() ); @@ -163,17 +161,6 @@ private LifecycleMapping lookupLifecycleMapping( final String packaging ) } } - private List getOrderedLifecycles() - { - // NOTE: The lifecycle order can affect implied execution ids so we better be deterministic. - - List lifecycles = new ArrayList<>( defaultLifeCycles.getLifeCycles() ); - - lifecycles.sort( Comparator.comparing( Lifecycle::getId ) ); - - return lifecycles; - } - private void parseLifecyclePhaseDefinitions( Map plugins, String phase, LifecyclePhase goals ) { InputSource inputSource = new InputSource(); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java index a06cd9f40efd..28847cabe5c2 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java @@ -48,6 +48,8 @@ import org.apache.maven.plugin.MavenPluginManager; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoExecutionRunner; +import org.apache.maven.plugin.MojosExecutionStrategy; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginIncompatibleException; @@ -80,17 +82,21 @@ public class MojoExecutor private final ReadWriteLock aggregatorLock = new ReentrantReadWriteLock(); + private final MojosExecutionStrategy mojosExecutionStrategy; + @Inject public MojoExecutor( BuildPluginManager pluginManager, MavenPluginManager mavenPluginManager, LifecycleDependencyResolver lifeCycleDependencyResolver, - ExecutionEventCatapult eventCatapult ) + ExecutionEventCatapult eventCatapult, + MojosExecutionStrategy mojosExecutionStrategy ) { this.pluginManager = pluginManager; this.mavenPluginManager = mavenPluginManager; this.lifeCycleDependencyResolver = lifeCycleDependencyResolver; this.eventCatapult = eventCatapult; + this.mojosExecutionStrategy = mojosExecutionStrategy; } public DependencyContext newDependencyContext( MavenSession session, List mojoExecutions ) @@ -148,21 +154,27 @@ else if ( Artifact.SCOPE_TEST.equals( classpath ) ) return Collections.unmodifiableCollection( scopes ); } - public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) + public void execute( final MavenSession session, + final List mojoExecutions, + final ProjectIndex projectIndex ) throws LifecycleExecutionException { - DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions ); + final DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions ); - PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() ); + final PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() ); - for ( MojoExecution mojoExecution : mojoExecutions ) + mojosExecutionStrategy.execute( mojoExecutions, session, new MojoExecutionRunner() { - execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); - } + @Override + public void run( MojoExecution mojoExecution ) throws LifecycleExecutionException + { + MojoExecutor.this.execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder ); + } + } ); } - public void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, + private void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, DependencyContext dependencyContext, PhaseRecorder phaseRecorder ) throws LifecycleExecutionException { diff --git a/maven-core/src/main/java/org/apache/maven/plugin/DefaultMojosExecutionStrategy.java b/maven-core/src/main/java/org/apache/maven/plugin/DefaultMojosExecutionStrategy.java new file mode 100644 index 000000000000..9507c7ad17c0 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/DefaultMojosExecutionStrategy.java @@ -0,0 +1,46 @@ +package org.apache.maven.plugin; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleExecutionException; + +import javax.inject.Named; +import javax.inject.Singleton; +import java.util.List; + +/** + * Default mojo execution strategy. It just iterates over mojo executions and runs one by one + */ +@Named +@Singleton +public class DefaultMojosExecutionStrategy implements MojosExecutionStrategy +{ + @Override + public void execute( List mojos, MavenSession session, MojoExecutionRunner mojoRunner ) + throws LifecycleExecutionException + { + for ( MojoExecution mojoExecution : mojos ) + { + mojoRunner.run( mojoExecution ); + } + + } +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/MojoExecutionRunner.java b/maven-core/src/main/java/org/apache/maven/plugin/MojoExecutionRunner.java new file mode 100644 index 000000000000..eab55859be18 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/MojoExecutionRunner.java @@ -0,0 +1,36 @@ +package org.apache.maven.plugin; + +/* + * 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. + */ + +import org.apache.maven.lifecycle.LifecycleExecutionException; + +/** + * Provides context for mojo execution. Invocation of {@link #run(MojoExecution)} will result in actual execution + */ +public interface MojoExecutionRunner +{ + /** + * Runs mojo execution + * + * @param execution mojo execution + * @throws LifecycleExecutionException + */ + void run( MojoExecution execution ) throws LifecycleExecutionException; +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/MojosExecutionStrategy.java b/maven-core/src/main/java/org/apache/maven/plugin/MojosExecutionStrategy.java new file mode 100644 index 000000000000..e4babf68d7db --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/MojosExecutionStrategy.java @@ -0,0 +1,45 @@ +package org.apache.maven.plugin; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleExecutionException; + +import java.util.List; + +/** + * Interface allows overriding default mojo execution strategy For example it is possible wrap some mojo execution to + * decorate default functionality or skip some executions + */ +public interface MojosExecutionStrategy +{ + + /** + * Entry point to the execution strategy + * + * @param mojos list of mojos representing a project build + * @param session current session + * @param mojoExecutionRunner mojo execution task which must be invoked by a strategy to actually run it + * @throws LifecycleExecutionException + */ + void execute( List mojos, MavenSession session, MojoExecutionRunner mojoExecutionRunner ) + throws LifecycleExecutionException; + +} 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 7da8ea88fa29..88813e6c9bdb 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 @@ -492,6 +492,21 @@ public T getConfiguredMojo( Class mojoInterface, MavenSession session, Mo ClassRealm pluginRealm = pluginDescriptor.getClassRealm(); + if ( pluginRealm == null ) + { + try + { + setupPluginRealm( pluginDescriptor, session, null, null, null ); + } + catch ( PluginResolutionException e ) + { + String msg = "Cannot setup plugin realm [mojoDescriptor=" + mojoDescriptor.getId() + + ", pluginDescriptor=" + pluginDescriptor.getId() + "]"; + throw new PluginConfigurationException( pluginDescriptor, msg, e ); + } + pluginRealm = pluginDescriptor.getClassRealm(); + } + if ( logger.isDebugEnabled() ) { logger.debug( "Configuring mojo " + mojoDescriptor.getId() + " from plugin realm " + pluginRealm ); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java index 59229d442b1e..046227a60432 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java @@ -93,8 +93,8 @@ public void testCustomLifecycle() DefaultLifecycles dl = new DefaultLifecycles( myLifecycles.stream() .collect( Collectors.toMap( l -> l.getId(), l -> l ) ) ); - assertThat( dl.getLifeCycles().get( 0 ).getId(), is( "default" ) ); - assertThat( dl.getLifeCycles().get( 1 ).getId(), is( "clean" ) ); + assertThat( dl.getLifeCycles().get( 0 ).getId(), is( "clean" ) ); + assertThat( dl.getLifeCycles().get( 1 ).getId(), is( "default" ) ); assertThat( dl.getLifeCycles().get( 2 ).getId(), is( "site" ) ); assertThat( dl.getLifeCycles().get( 3 ).getId(), is( "wrapper" ) ); assertThat( dl.getLifeCycles().get( 4 ).getId(), is( "etl" ) ); diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java index feedd1ed8266..57eacb1fc6f4 100644 --- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java @@ -21,14 +21,15 @@ import org.apache.maven.lifecycle.internal.ExecutionEventCatapult; import org.apache.maven.lifecycle.internal.LifecycleDependencyResolver; import org.apache.maven.lifecycle.internal.MojoExecutor; -import org.apache.maven.lifecycle.internal.PhaseRecorder; import org.apache.maven.lifecycle.internal.ProjectIndex; import org.apache.maven.plugin.BuildPluginManager; import org.apache.maven.plugin.MavenPluginManager; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojosExecutionStrategy; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; import java.util.ArrayList; import java.util.Collections; @@ -47,24 +48,23 @@ public MojoExecutorStub( BuildPluginManager pluginManager, MavenPluginManager mavenPluginManager, LifecycleDependencyResolver lifeCycleDependencyResolver, - ExecutionEventCatapult eventCatapult ) + ExecutionEventCatapult eventCatapult, + MojosExecutionStrategy mojosExecutionStrategy ) { - super( pluginManager, mavenPluginManager, lifeCycleDependencyResolver, eventCatapult ); + super( pluginManager, mavenPluginManager, lifeCycleDependencyResolver, eventCatapult, mojosExecutionStrategy ); } @Override - public void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, - DependencyContext dependencyContext, PhaseRecorder phaseRecorder ) + public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) throws LifecycleExecutionException { - executions.add( mojoExecution ); + executions.addAll( mojoExecutions ); } @Override - public void execute( MavenSession session, List mojoExecutions, ProjectIndex projectIndex ) - throws LifecycleExecutionException + public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session, ProjectIndex projectIndex ) throws LifecycleExecutionException { - executions.addAll(mojoExecutions); + return null; }