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.List;
22 import java.util.Optional;
23 import java.util.Properties;
24 import java.util.Set;
25 import java.util.stream.Collectors;
26 import javax.inject.Inject;
27 import javax.inject.Named;
28 import javax.inject.Singleton;
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.execution.BuildFailure;
31 import org.apache.maven.execution.ExecutionEvent;
32 import org.apache.maven.execution.MavenExecutionRequest;
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.feature.Features;
35 import org.apache.maven.internal.MultilineMessageHelper;
36 import org.apache.maven.lifecycle.LifecycleExecutionException;
37 import org.apache.maven.lifecycle.LifecycleNotFoundException;
38 import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
39 import org.apache.maven.lifecycle.MavenExecutionPlan;
40 import org.apache.maven.lifecycle.internal.DefaultLifecyclePluginAnalyzer;
41 import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
42 import org.apache.maven.lifecycle.internal.LifecycleDebugLogger;
43 import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
44 import org.apache.maven.lifecycle.internal.ReactorContext;
45 import org.apache.maven.lifecycle.internal.TaskSegment;
46 import org.apache.maven.model.Plugin;
47 import org.apache.maven.plugin.InvalidPluginDescriptorException;
48 import org.apache.maven.plugin.MojoExecution;
49 import org.apache.maven.plugin.MojoNotFoundException;
50 import org.apache.maven.plugin.PluginDescriptorParsingException;
51 import org.apache.maven.plugin.PluginNotFoundException;
52 import org.apache.maven.plugin.PluginResolutionException;
53 import org.apache.maven.plugin.descriptor.MojoDescriptor;
54 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
55 import org.apache.maven.plugin.version.PluginVersionResolutionException;
56 import org.apache.maven.project.MavenProject;
57 import org.codehaus.plexus.classworlds.realm.ClassRealm;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67
68
69 @Named
70 @Singleton
71 public class BuilderCommon {
72 private final Logger logger;
73 private final LifecycleDebugLogger lifecycleDebugLogger;
74 private final LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
75 private final ExecutionEventCatapult eventCatapult;
76
77 @Inject
78 public BuilderCommon(
79 LifecycleDebugLogger lifecycleDebugLogger,
80 LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator,
81 ExecutionEventCatapult eventCatapult) {
82 this.logger = LoggerFactory.getLogger(getClass());
83 this.lifecycleDebugLogger = lifecycleDebugLogger;
84 this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
85 this.eventCatapult = eventCatapult;
86 }
87
88
89
90
91 BuilderCommon(
92 LifecycleDebugLogger lifecycleDebugLogger,
93 LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator,
94 ExecutionEventCatapult eventCatapult,
95 Logger logger) {
96 this.lifecycleDebugLogger = lifecycleDebugLogger;
97 this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
98 this.eventCatapult = eventCatapult;
99 this.logger = logger;
100 }
101
102 public MavenExecutionPlan resolveBuildPlan(
103 MavenSession session, MavenProject project, TaskSegment taskSegment, Set<Artifact> projectArtifacts)
104 throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
105 PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
106 NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
107 LifecycleExecutionException {
108 MavenExecutionPlan executionPlan =
109 lifeCycleExecutionPlanCalculator.calculateExecutionPlan(session, project, taskSegment.getTasks());
110
111 lifecycleDebugLogger.debugProjectPlan(project, executionPlan);
112
113
114
115
116 Properties userProperties = session.getUserProperties();
117 if (Features.buildConsumer(userProperties).isActive()) {
118 Optional<MojoExecution> gpgMojo = executionPlan.getMojoExecutions().stream()
119 .filter(m -> "maven-gpg-plugin".equals(m.getArtifactId())
120 && "org.apache.maven.plugins".equals(m.getGroupId()))
121 .findAny();
122
123 if (gpgMojo.isPresent()) {
124 throw new LifecycleExecutionException("The maven-gpg-plugin is not supported by Maven 4."
125 + " Verify if there is a compatible signing solution,"
126 + " add -D" + Features.buildConsumer(userProperties).propertyName() + "=false"
127 + " or use Maven 3.");
128 }
129 }
130
131 if (session.getRequest().getDegreeOfConcurrency() > 1
132 && session.getProjects().size() > 1) {
133 final Set<Plugin> unsafePlugins = executionPlan.getNonThreadSafePlugins();
134 if (!unsafePlugins.isEmpty()) {
135 for (String s : MultilineMessageHelper.format(
136 "Your build is requesting parallel execution, but this project contains the following "
137 + "plugin(s) that have goals not marked as thread-safe to support parallel execution.",
138 "While this /may/ work fine, please look for plugin updates and/or "
139 + "request plugins be made thread-safe.",
140 "If reporting an issue, report it against the plugin in question, not against Apache Maven.")) {
141 logger.warn(s);
142 }
143 if (logger.isDebugEnabled()) {
144 final Set<MojoDescriptor> unsafeGoals = executionPlan.getNonThreadSafeMojos();
145 logger.warn("The following goals are not marked as thread-safe in " + project.getName() + ":");
146 for (MojoDescriptor unsafeGoal : unsafeGoals) {
147 logger.warn(" " + unsafeGoal.getId());
148 }
149 } else {
150 logger.warn("The following plugins are not marked as thread-safe in " + project.getName() + ":");
151 for (Plugin unsafePlugin : unsafePlugins) {
152 logger.warn(" " + unsafePlugin.getId());
153 }
154 logger.warn("");
155 logger.warn("Enable verbose output (-X) to see precisely which goals are not marked as"
156 + " thread-safe.");
157 }
158 logger.warn(MultilineMessageHelper.separatorLine());
159 }
160 }
161
162 final String defaulModelId = DefaultLifecyclePluginAnalyzer.DEFAULTLIFECYCLEBINDINGS_MODELID;
163
164 List<String> unversionedPlugins = executionPlan.getMojoExecutions().stream()
165 .map(MojoExecution::getPlugin)
166 .filter(p -> p.getLocation("version") != null
167 && p.getLocation("version").getSource() != null
168 && defaulModelId.equals(
169 p.getLocation("version").getSource().getModelId()))
170 .distinct()
171 .map(Plugin::getArtifactId)
172 .collect(Collectors.toList());
173
174 if (!unversionedPlugins.isEmpty()) {
175 logger.warn("Version not locked for default bindings plugins " + unversionedPlugins
176 + ", you should define versions in pluginManagement section of your " + "pom.xml or parent");
177 }
178
179 return executionPlan;
180 }
181
182 public void handleBuildError(
183 final ReactorContext buildContext,
184 final MavenSession rootSession,
185 final MavenSession currentSession,
186 final MavenProject mavenProject,
187 Throwable t,
188 final long buildStartTime) {
189
190 long buildEndTime = System.currentTimeMillis();
191 buildContext.getResult().addException(t);
192 buildContext.getResult().addBuildSummary(new BuildFailure(mavenProject, buildEndTime - buildStartTime, t));
193
194
195 if (t instanceof Exception && !(t instanceof RuntimeException)) {
196 eventCatapult.fire(ExecutionEvent.Type.ProjectFailed, currentSession, null, (Exception) t);
197 }
198
199
200 if (t instanceof RuntimeException || !(t instanceof Exception)) {
201
202
203 buildContext.getReactorBuildStatus().halt();
204 } else if (MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(rootSession.getReactorFailureBehavior())) {
205
206 } else if (MavenExecutionRequest.REACTOR_FAIL_AT_END.equals(rootSession.getReactorFailureBehavior())) {
207
208 buildContext.getReactorBuildStatus().blackList(mavenProject);
209 } else if (MavenExecutionRequest.REACTOR_FAIL_FAST.equals(rootSession.getReactorFailureBehavior())) {
210 buildContext.getReactorBuildStatus().halt();
211 } else {
212 logger.error("invalid reactor failure behavior " + rootSession.getReactorFailureBehavior());
213 buildContext.getReactorBuildStatus().halt();
214 }
215 }
216
217 public static void attachToThread(MavenProject currentProject) {
218 ClassRealm projectRealm = currentProject.getClassRealm();
219 if (projectRealm != null) {
220 Thread.currentThread().setContextClassLoader(projectRealm);
221 }
222 }
223
224
225
226
227 public static String getKey(MavenProject project) {
228 return project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion();
229 }
230 }