View Javadoc

1   package org.apache.maven.lifecycle.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.InternalErrorException;
23  import org.apache.maven.artifact.Artifact;
24  import org.apache.maven.execution.BuildFailure;
25  import org.apache.maven.execution.ExecutionEvent;
26  import org.apache.maven.execution.MavenExecutionRequest;
27  import org.apache.maven.execution.MavenSession;
28  import org.apache.maven.lifecycle.LifecycleExecutionException;
29  import org.apache.maven.lifecycle.LifecycleNotFoundException;
30  import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
31  import org.apache.maven.lifecycle.MavenExecutionPlan;
32  import org.apache.maven.model.Plugin;
33  import org.apache.maven.plugin.InvalidPluginDescriptorException;
34  import org.apache.maven.plugin.MojoNotFoundException;
35  import org.apache.maven.plugin.PluginDescriptorParsingException;
36  import org.apache.maven.plugin.PluginNotFoundException;
37  import org.apache.maven.plugin.PluginResolutionException;
38  import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
39  import org.apache.maven.plugin.version.PluginVersionResolutionException;
40  import org.apache.maven.project.MavenProject;
41  import org.codehaus.plexus.classworlds.realm.ClassRealm;
42  import org.codehaus.plexus.component.annotations.Component;
43  import org.codehaus.plexus.component.annotations.Requirement;
44  import org.codehaus.plexus.logging.Logger;
45  
46  import java.util.Set;
47  
48  /**
49   * Common code that is shared by the LifecycleModuleBuilder and the LifeCycleWeaveBuilder
50   * 
51   * @since 3.0
52   * @author Kristian Rosenvold
53   *         Builds one or more lifecycles for a full module
54   *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
55   */
56  @Component( role = BuilderCommon.class )
57  public class BuilderCommon
58  {
59      @Requirement
60      private LifecycleDebugLogger lifecycleDebugLogger;
61  
62      @Requirement
63      private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
64  
65      @Requirement
66      private ExecutionEventCatapult eventCatapult;
67  
68      @Requirement
69      private Logger logger;
70  
71  
72      @SuppressWarnings( { "UnusedDeclaration" } )
73      public BuilderCommon()
74      {
75      }
76  
77      public BuilderCommon( LifecycleDebugLogger lifecycleDebugLogger,
78                            LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator, Logger logger )
79      {
80          this.lifecycleDebugLogger = lifecycleDebugLogger;
81          this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
82          this.logger = logger;
83      }
84  
85      public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject project, TaskSegment taskSegment,
86                                                  Set<Artifact> projectArtifacts )
87          throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
88          PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
89          NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
90          LifecycleExecutionException
91      {
92          MavenExecutionPlan executionPlan =
93              lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, project, taskSegment.getTasks() );
94  
95          lifecycleDebugLogger.debugProjectPlan( project, executionPlan );
96  
97          if ( session.getRequest().isThreadConfigurationPresent() )
98          {
99              final Set<Plugin> unsafePlugins = executionPlan.getNonThreadSafePlugins();
100             if ( !unsafePlugins.isEmpty() )
101             {
102                 logger.warn( "*****************************************************************" );
103                 logger.warn( "* Your build is requesting parallel execution, but project      *" );
104                 logger.warn( "* contains the following plugin(s) that are not marked as       *" );
105                 logger.warn( "* @threadSafe to support parallel building.                     *" );
106                 logger.warn( "* While this /may/ work fine, please look for plugin updates    *" );
107                 logger.warn( "* and/or request plugins be made thread-safe.                   *" );
108                 logger.warn( "* If reporting an issue, report it against the plugin in        *" );
109                 logger.warn( "* question, not against maven-core                              *" );
110                 logger.warn( "*****************************************************************" );
111                 logger.warn( "The following plugins are not marked @threadSafe in " + project.getName() + ":" );
112                 for ( Plugin unsafePlugin : unsafePlugins )
113                 {
114                     logger.warn( unsafePlugin.getId() );
115                 }
116                 logger.warn( "*****************************************************************" );
117             }
118         }
119 
120         return executionPlan;
121     }
122 
123     public void handleBuildError( final ReactorContext buildContext, final MavenSession rootSession,
124                                   final MavenProject mavenProject, Exception e, final long buildStartTime )
125     {
126         if ( e instanceof RuntimeException )
127         {
128             e = new InternalErrorException( "Internal error: " + e, e );
129         }
130 
131         buildContext.getResult().addException( e );
132 
133         long buildEndTime = System.currentTimeMillis();
134 
135         buildContext.getResult().addBuildSummary( new BuildFailure( mavenProject, buildEndTime - buildStartTime, e ) );
136 
137         eventCatapult.fire( ExecutionEvent.Type.ProjectFailed, rootSession, null );
138 
139         if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( rootSession.getReactorFailureBehavior() ) )
140         {
141             // continue the build
142         }
143         else if ( MavenExecutionRequest.REACTOR_FAIL_AT_END.equals( rootSession.getReactorFailureBehavior() ) )
144         {
145             // continue the build but ban all projects that depend on the failed one
146             buildContext.getReactorBuildStatus().blackList( mavenProject );
147         }
148         else if ( MavenExecutionRequest.REACTOR_FAIL_FAST.equals( rootSession.getReactorFailureBehavior() ) )
149         {
150             buildContext.getReactorBuildStatus().halt();
151         }
152         else
153         {
154             throw new IllegalArgumentException(
155                 "invalid reactor failure behavior " + rootSession.getReactorFailureBehavior() );
156         }
157     }
158 
159     public static void attachToThread( MavenProject currentProject )
160     {
161         ClassRealm projectRealm = currentProject.getClassRealm();
162         if ( projectRealm != null )
163         {
164             Thread.currentThread().setContextClassLoader( projectRealm );
165         }
166     }
167 
168     // Todo: I'm really wondering where this method belongs; smells like it should be on MavenProject, but for some reason
169     // it isn't ? This localization is kind-of a code smell.
170 
171     public static String getKey( MavenProject project )
172     {
173         return project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion();
174     }
175 
176 
177 }