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