aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java')
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java521
1 files changed, 521 insertions, 0 deletions
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
new file mode 100644
index 00000000..94e75e02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -0,0 +1,521 @@
+package org.apache.maven;
+
+/*
+ * 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 java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+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.execution.ProjectDependencyGraph;
+import org.apache.maven.graph.GraphBuilder;
+import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
+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.Result;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
+import org.apache.maven.session.scope.internal.SessionScope;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.util.repository.ChainedWorkspaceReader;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = Maven.class )
+public class DefaultMaven
+ implements Maven
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ protected ProjectBuilder projectBuilder;
+
+ @Requirement
+ private LifecycleStarter lifecycleStarter;
+
+ @Requirement
+ protected PlexusContainer container;
+
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private SessionScope sessionScope;
+
+ @Requirement
+ private DefaultRepositorySystemSessionFactory repositorySessionFactory;
+
+ @Requirement( hint = GraphBuilder.HINT )
+ private GraphBuilder graphBuilder;
+
+ @Override
+ public MavenExecutionResult execute( MavenExecutionRequest request )
+ {
+ MavenExecutionResult result;
+
+ try
+ {
+ result = doExecute( request );
+ }
+ catch ( OutOfMemoryError e )
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(), e );
+ }
+ catch ( RuntimeException e )
+ {
+ //TODO Hack to make the cycle detection the same for the new graph builder
+ if ( e.getCause() instanceof ProjectCycleException )
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(), e.getCause() );
+ }
+ else
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(),
+ new InternalErrorException( "Internal error: " + e, e ) );
+ }
+ }
+ finally
+ {
+ legacySupport.setSession( null );
+ }
+
+ return result;
+ }
+
+ //
+ // 1) Setup initial properties.
+ //
+ // 2) Validate local repository directory is accessible.
+ //
+ // 3) Create RepositorySystemSession.
+ //
+ // 4) Create MavenSession.
+ //
+ // 5) Execute AbstractLifecycleParticipant.afterSessionStart(session)
+ //
+ // 6) Get reactor projects looking for general POM errors
+ //
+ // 7) Create ProjectDependencyGraph using trimming which takes into account --projects and reactor mode.
+ // This ensures that the projects passed into the ReactorReader are only those specified.
+ //
+ // 8) Create ReactorReader with the getProjectMap( projects ). NOTE that getProjectMap(projects) is the code that
+ // checks for duplicate projects definitions in the build. Ideally this type of duplicate checking should be
+ // part of getting the reactor projects in 6). The duplicate checking is conflated with getProjectMap(projects).
+ //
+ // 9) Execute AbstractLifecycleParticipant.afterProjectsRead(session)
+ //
+ // 10) Create ProjectDependencyGraph without trimming (as trimming was done in 7). A new topological sort is
+ // required after the execution of 9) as the AbstractLifecycleParticipants are free to mutate the MavenProject
+ // instances, which may change dependencies which can, in turn, affect the build order.
+ //
+ // 11) Execute LifecycleStarter.start()
+ //
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private MavenExecutionResult doExecute( MavenExecutionRequest request )
+ {
+ request.setStartTime( new Date() );
+
+ MavenExecutionResult result = new DefaultMavenExecutionResult();
+
+ try
+ {
+ validateLocalRepository( request );
+ }
+ catch ( LocalRepositoryNotAccessibleException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ //
+ // We enter the session scope right after the MavenSession creation and before any of the
+ // AbstractLifecycleParticipant lookups
+ // so that @SessionScoped components can be @Injected into AbstractLifecycleParticipants.
+ //
+ sessionScope.enter();
+ try
+ {
+ DefaultRepositorySystemSession repoSession =
+ (DefaultRepositorySystemSession) newRepositorySession( request );
+ MavenSession session = new MavenSession( container, repoSession, request, result );
+
+ sessionScope.seed( MavenSession.class, session );
+
+ legacySupport.setSession( session );
+
+ return doExecute( request, session, result, repoSession );
+ }
+ finally
+ {
+ sessionScope.exit();
+ }
+ }
+
+ private MavenExecutionResult doExecute( MavenExecutionRequest request, MavenSession session,
+ MavenExecutionResult result, DefaultRepositorySystemSession repoSession )
+ {
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( Collections
+ .<MavenProject>emptyList() ) )
+ {
+ listener.afterSessionStart( session );
+ }
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null );
+
+ Result<? extends ProjectDependencyGraph> graphResult = buildGraph( session, result );
+
+ if ( graphResult.hasErrors() )
+ {
+ return addExceptionToResult( result,
+ Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+ .getException() );
+ }
+
+ try
+ {
+ session.setProjectMap( getProjectMap( session.getProjects() ) );
+ }
+ catch ( DuplicateProjectException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ WorkspaceReader reactorWorkspace;
+ try
+ {
+ reactorWorkspace = container.lookup( WorkspaceReader.class, ReactorReader.HINT );
+ }
+ catch ( ComponentLookupException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ //
+ // Desired order of precedence for local artifact repositories
+ //
+ // Reactor
+ // Workspace
+ // User Local Repository
+ //
+ repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorWorkspace,
+ repoSession.getWorkspaceReader() ) );
+
+ repoSession.setReadOnly();
+
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( session.getProjects() ) )
+ {
+ Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
+
+ listener.afterProjectsRead( session );
+ }
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+
+ //
+ // The projects need to be topologically after the participants have run their afterProjectsRead(session)
+ // because the participant is free to change the dependencies of a project which can potentially change the
+ // topological order of the projects, and therefore can potentially change the build order.
+ //
+ // Note that participants may affect the topological order of the projects but it is
+ // not expected that a participant will add or remove projects from the session.
+ //
+
+ graphResult = buildGraph( session, result );
+
+ if ( graphResult.hasErrors() )
+ {
+ return addExceptionToResult( result,
+ Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+ .getException() );
+ }
+
+ try
+ {
+ if ( result.hasExceptions() )
+ {
+ return result;
+ }
+
+ result.setTopologicallySortedProjects( session.getProjects() );
+
+ result.setProject( session.getTopLevelProject() );
+
+ lifecycleStarter.execute( session );
+
+ validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );
+
+ if ( session.getResult().hasExceptions() )
+ {
+ return addExceptionToResult( result, session.getResult().getExceptions().get( 0 ) );
+ }
+ }
+ finally
+ {
+ try
+ {
+ afterSessionEnd( session.getProjects(), session );
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+ }
+
+ return result;
+ }
+
+ private void afterSessionEnd( Collection<MavenProject> projects, MavenSession session )
+ throws MavenExecutionException
+ {
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( projects ) )
+ {
+ Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
+
+ listener.afterSessionEnd( session );
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+ }
+
+ public RepositorySystemSession newRepositorySession( MavenExecutionRequest request )
+ {
+ return repositorySessionFactory.newRepositorySession( request );
+ }
+
+ private void validateLocalRepository( MavenExecutionRequest request )
+ throws LocalRepositoryNotAccessibleException
+ {
+ File localRepoDir = request.getLocalRepositoryPath();
+
+ logger.debug( "Using local repository at " + localRepoDir );
+
+ localRepoDir.mkdirs();
+
+ if ( !localRepoDir.isDirectory() )
+ {
+ throw new LocalRepositoryNotAccessibleException( "Could not create local repository at " + localRepoDir );
+ }
+ }
+
+ private Collection<AbstractMavenLifecycleParticipant> getLifecycleParticipants( Collection<MavenProject> projects )
+ {
+ Collection<AbstractMavenLifecycleParticipant> lifecycleListeners =
+ new LinkedHashSet<AbstractMavenLifecycleParticipant>();
+
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ try
+ {
+ lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // this is just silly, lookupList should return an empty list!
+ logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
+ }
+
+ Collection<ClassLoader> scannedRealms = new HashSet<ClassLoader>();
+
+ for ( MavenProject project : projects )
+ {
+ ClassLoader projectRealm = project.getClassRealm();
+
+ if ( projectRealm != null && scannedRealms.add( projectRealm ) )
+ {
+ Thread.currentThread().setContextClassLoader( projectRealm );
+
+ try
+ {
+ lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // this is just silly, lookupList should return an empty list!
+ logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
+ }
+ }
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+
+ return lifecycleListeners;
+ }
+
+ private MavenExecutionResult addExceptionToResult( MavenExecutionResult result, Throwable e )
+ {
+ if ( !result.getExceptions().contains( e ) )
+ {
+ result.addException( e );
+ }
+
+ return result;
+ }
+
+ private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
+ {
+ Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
+
+ for ( MavenProject project : projects )
+ {
+ for ( List<String> profileIds : project.getInjectedProfileIds().values() )
+ {
+ notActivatedProfileIds.removeAll( profileIds );
+ }
+ }
+
+ for ( String notActivatedProfileId : notActivatedProfileIds )
+ {
+ logger.warn( "The requested profile \"" + notActivatedProfileId
+ + "\" could not be activated because it does not exist." );
+ }
+ }
+
+ private Map<String, MavenProject> getProjectMap( Collection<MavenProject> projects )
+ throws DuplicateProjectException
+ {
+ Map<String, MavenProject> index = new LinkedHashMap<String, MavenProject>();
+ Map<String, List<File>> collisions = new LinkedHashMap<String, List<File>>();
+
+ for ( MavenProject project : projects )
+ {
+ String projectId = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+
+ MavenProject collision = index.get( projectId );
+
+ if ( collision == null )
+ {
+ index.put( projectId, project );
+ }
+ else
+ {
+ List<File> pomFiles = collisions.get( projectId );
+
+ if ( pomFiles == null )
+ {
+ pomFiles = new ArrayList<File>( Arrays.asList( collision.getFile(), project.getFile() ) );
+ collisions.put( projectId, pomFiles );
+ }
+ else
+ {
+ pomFiles.add( project.getFile() );
+ }
+ }
+ }
+
+ if ( !collisions.isEmpty() )
+ {
+ throw new DuplicateProjectException( "Two or more projects in the reactor"
+ + " have the same identifier, please make sure that <groupId>:<artifactId>:<version>"
+ + " is unique for each project: " + collisions, collisions );
+ }
+
+ return index;
+ }
+
+ private Result<? extends ProjectDependencyGraph> buildGraph( MavenSession session, MavenExecutionResult result )
+ {
+ Result<? extends ProjectDependencyGraph> graphResult = graphBuilder.build( session );
+ for ( ModelProblem problem : graphResult.getProblems() )
+ {
+ if ( problem.getSeverity() == ModelProblem.Severity.WARNING )
+ {
+ logger.warn( problem.toString() );
+ }
+ else
+ {
+ logger.error( problem.toString() );
+ }
+ }
+
+ if ( !graphResult.hasErrors() )
+ {
+ ProjectDependencyGraph projectDependencyGraph = graphResult.get();
+ session.setProjects( projectDependencyGraph.getSortedProjects() );
+ session.setAllProjects( projectDependencyGraph.getSortedProjects() );
+ session.setProjectDependencyGraph( projectDependencyGraph );
+ }
+
+ return graphResult;
+ }
+
+ @Deprecated
+ // 5 January 2014
+ protected Logger getLogger()
+ {
+ return logger;
+ }
+}