1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.lifecycle.internal.builder;
20
21 import java.util.Set;
22
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.internal.MultilineMessageHelper;
29 import org.apache.maven.lifecycle.LifecycleExecutionException;
30 import org.apache.maven.lifecycle.LifecycleNotFoundException;
31 import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
32 import org.apache.maven.lifecycle.MavenExecutionPlan;
33 import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
34 import org.apache.maven.lifecycle.internal.LifecycleDebugLogger;
35 import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
36 import org.apache.maven.lifecycle.internal.ReactorContext;
37 import org.apache.maven.lifecycle.internal.TaskSegment;
38 import org.apache.maven.model.Plugin;
39 import org.apache.maven.plugin.InvalidPluginDescriptorException;
40 import org.apache.maven.plugin.MojoNotFoundException;
41 import org.apache.maven.plugin.PluginDescriptorParsingException;
42 import org.apache.maven.plugin.PluginNotFoundException;
43 import org.apache.maven.plugin.PluginResolutionException;
44 import org.apache.maven.plugin.descriptor.MojoDescriptor;
45 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
46 import org.apache.maven.plugin.version.PluginVersionResolutionException;
47 import org.apache.maven.project.MavenProject;
48 import org.codehaus.plexus.classworlds.realm.ClassRealm;
49 import org.codehaus.plexus.component.annotations.Component;
50 import org.codehaus.plexus.component.annotations.Requirement;
51 import org.codehaus.plexus.logging.Logger;
52
53
54
55
56
57
58
59
60
61 @Component(role = BuilderCommon.class)
62 public class BuilderCommon {
63 @Requirement
64 private LifecycleDebugLogger lifecycleDebugLogger;
65
66 @Requirement
67 private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
68
69 @Requirement
70 private ExecutionEventCatapult eventCatapult;
71
72 @Requirement
73 private Logger logger;
74
75 public BuilderCommon() {}
76
77 public BuilderCommon(
78 LifecycleDebugLogger lifecycleDebugLogger,
79 LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator,
80 Logger logger) {
81 this.lifecycleDebugLogger = lifecycleDebugLogger;
82 this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
83 this.logger = logger;
84 }
85
86 public MavenExecutionPlan resolveBuildPlan(
87 MavenSession session, MavenProject project, TaskSegment taskSegment, Set<Artifact> projectArtifacts)
88 throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
89 PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
90 NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
91 LifecycleExecutionException {
92 MavenExecutionPlan executionPlan =
93 lifeCycleExecutionPlanCalculator.calculateExecutionPlan(session, project, taskSegment.getTasks());
94
95 lifecycleDebugLogger.debugProjectPlan(project, executionPlan);
96
97 if (session.getRequest().getDegreeOfConcurrency() > 1
98 && session.getProjects().size() > 1) {
99 final Set<Plugin> unsafePlugins = executionPlan.getNonThreadSafePlugins();
100 if (!unsafePlugins.isEmpty()) {
101 for (String s : MultilineMessageHelper.format(
102 "Your build is requesting parallel execution, but this project contains the following "
103 + "plugin(s) that have goals not marked as thread-safe to support parallel execution.",
104 "While this /may/ work fine, please look for plugin updates and/or "
105 + "request plugins be made thread-safe.",
106 "If reporting an issue, report it against the plugin in question, not against Apache Maven.")) {
107 logger.warn(s);
108 }
109 if (logger.isDebugEnabled()) {
110 final Set<MojoDescriptor> unsafeGoals = executionPlan.getNonThreadSafeMojos();
111 logger.warn("The following goals are not marked as thread-safe in " + project.getName() + ":");
112 for (MojoDescriptor unsafeGoal : unsafeGoals) {
113 logger.warn(" " + unsafeGoal.getId());
114 }
115 } else {
116 logger.warn("The following plugins are not marked as thread-safe in " + project.getName() + ":");
117 for (Plugin unsafePlugin : unsafePlugins) {
118 logger.warn(" " + unsafePlugin.getId());
119 }
120 logger.warn("");
121 logger.warn("Enable debug to see precisely which goals are not marked as thread-safe.");
122 }
123 logger.warn(MultilineMessageHelper.separatorLine());
124 }
125 }
126
127 return executionPlan;
128 }
129
130 public void handleBuildError(
131 final ReactorContext buildContext,
132 final MavenSession rootSession,
133 final MavenSession currentSession,
134 final MavenProject mavenProject,
135 Throwable t,
136 final long buildStartTime) {
137
138 long buildEndTime = System.currentTimeMillis();
139 buildContext.getResult().addException(t);
140 buildContext.getResult().addBuildSummary(new BuildFailure(mavenProject, buildEndTime - buildStartTime, t));
141
142
143 if (t instanceof Exception && !(t instanceof RuntimeException)) {
144 eventCatapult.fire(ExecutionEvent.Type.ProjectFailed, currentSession, null, (Exception) t);
145 }
146
147
148 if (t instanceof RuntimeException || !(t instanceof Exception)) {
149
150
151 buildContext.getReactorBuildStatus().halt();
152 } else if (MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(rootSession.getReactorFailureBehavior())) {
153
154 } else if (MavenExecutionRequest.REACTOR_FAIL_AT_END.equals(rootSession.getReactorFailureBehavior())) {
155
156 buildContext.getReactorBuildStatus().blackList(mavenProject);
157 } else if (MavenExecutionRequest.REACTOR_FAIL_FAST.equals(rootSession.getReactorFailureBehavior())) {
158 buildContext.getReactorBuildStatus().halt();
159 } else {
160 logger.error("invalid reactor failure behavior " + rootSession.getReactorFailureBehavior());
161 buildContext.getReactorBuildStatus().halt();
162 }
163 }
164
165 public static void attachToThread(MavenProject currentProject) {
166 ClassRealm projectRealm = currentProject.getClassRealm();
167 if (projectRealm != null) {
168 Thread.currentThread().setContextClassLoader(projectRealm);
169 }
170 }
171
172
173
174
175 public static String getKey(MavenProject project) {
176 return project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion();
177 }
178 }