1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.exception;
20
21 import javax.inject.Named;
22 import javax.inject.Singleton;
23
24 import java.io.IOException;
25 import java.net.ConnectException;
26 import java.net.UnknownHostException;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import org.apache.maven.lifecycle.LifecycleExecutionException;
31 import org.apache.maven.model.building.ModelProblem;
32 import org.apache.maven.model.building.ModelProblemUtils;
33 import org.apache.maven.plugin.AbstractMojoExecutionException;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.MojoFailureException;
36 import org.apache.maven.plugin.PluginContainerException;
37 import org.apache.maven.plugin.PluginExecutionException;
38 import org.apache.maven.project.ProjectBuildingException;
39 import org.apache.maven.project.ProjectBuildingResult;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 @Named
90 @Singleton
91 public class DefaultExceptionHandler implements ExceptionHandler {
92
93 public ExceptionSummary handleException(Throwable exception) {
94 return handle("", exception);
95 }
96
97 private ExceptionSummary handle(String message, Throwable exception) {
98 String reference = getReference(exception);
99
100 List<ExceptionSummary> children = null;
101
102 if (exception instanceof ProjectBuildingException) {
103 List<ProjectBuildingResult> results = ((ProjectBuildingException) exception).getResults();
104
105 children = new ArrayList<>();
106
107 for (ProjectBuildingResult result : results) {
108 ExceptionSummary child = handle(result);
109 if (child != null) {
110 children.add(child);
111 }
112 }
113
114 message = "The build could not read " + children.size() + " project" + (children.size() == 1 ? "" : "s");
115 } else {
116 message = getMessage(message, exception);
117 }
118
119 return new ExceptionSummary(exception, message, reference, children);
120 }
121
122 private ExceptionSummary handle(ProjectBuildingResult result) {
123 List<ExceptionSummary> children = new ArrayList<>();
124
125 for (ModelProblem problem : result.getProblems()) {
126 ExceptionSummary child = handle(problem, result.getProjectId());
127 if (child != null) {
128 children.add(child);
129 }
130 }
131
132 if (children.isEmpty()) {
133 return null;
134 }
135
136 String message = System.lineSeparator()
137 + "The project " + (result.getProjectId().isEmpty() ? "" : result.getProjectId() + " ")
138 + "(" + result.getPomFile() + ") has "
139 + children.size() + " error" + (children.size() == 1 ? "" : "s");
140
141 return new ExceptionSummary(null, message, null, children);
142 }
143
144 private ExceptionSummary handle(ModelProblem problem, String projectId) {
145 if (ModelProblem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) {
146 String message = problem.getMessage();
147
148 String location = ModelProblemUtils.formatLocation(problem, projectId);
149
150 if (!location.isEmpty()) {
151 message += " @ " + location;
152 }
153
154 return handle(message, problem.getException());
155 } else {
156 return null;
157 }
158 }
159
160 private String getReference(Throwable exception) {
161 String reference = "";
162
163 if (exception != null) {
164 if (exception instanceof MojoExecutionException) {
165 reference = MojoExecutionException.class.getSimpleName();
166
167 Throwable cause = exception.getCause();
168 if (cause instanceof IOException) {
169 cause = cause.getCause();
170 if (cause instanceof ConnectException) {
171 reference = ConnectException.class.getSimpleName();
172 }
173 }
174 } else if (exception instanceof MojoFailureException) {
175 reference = MojoFailureException.class.getSimpleName();
176 } else if (exception instanceof LinkageError) {
177 reference = LinkageError.class.getSimpleName();
178 } else if (exception instanceof PluginExecutionException) {
179 Throwable cause = exception.getCause();
180
181 if (cause instanceof PluginContainerException) {
182 Throwable cause2 = cause.getCause();
183
184 if (cause2 instanceof NoClassDefFoundError) {
185 String message = cause2.getMessage();
186 if (message != null && message.contains("org/sonatype/aether/")) {
187 reference = "AetherClassNotFound";
188 }
189 }
190 }
191
192 if (reference == null || reference.isEmpty()) {
193 reference = getReference(cause);
194 }
195
196 if (reference == null || reference.isEmpty()) {
197 reference = exception.getClass().getSimpleName();
198 }
199 } else if (exception instanceof LifecycleExecutionException) {
200 reference = getReference(exception.getCause());
201 } else if (isNoteworthyException(exception)) {
202 reference = exception.getClass().getSimpleName();
203 }
204 }
205
206 if ((reference != null && !reference.isEmpty()) && !reference.startsWith("http:")) {
207 reference = "http://cwiki.apache.org/confluence/display/MAVEN/" + reference;
208 }
209
210 return reference;
211 }
212
213 private boolean isNoteworthyException(Throwable exception) {
214 if (exception == null) {
215 return false;
216 } else if (exception instanceof Error) {
217 return true;
218 } else if (exception instanceof RuntimeException) {
219 return false;
220 } else {
221 return !exception.getClass().getName().startsWith("java");
222 }
223 }
224
225 private String getMessage(String message, Throwable exception) {
226 String fullMessage = (message != null) ? message : "";
227
228
229 for (Throwable t = exception; t != null && t != t.getCause(); t = t.getCause()) {
230 String exceptionMessage = t.getMessage();
231
232 if (t instanceof AbstractMojoExecutionException) {
233 String longMessage = ((AbstractMojoExecutionException) t).getLongMessage();
234 if (longMessage != null && !longMessage.isEmpty()) {
235 if ((exceptionMessage == null || exceptionMessage.isEmpty())
236 || longMessage.contains(exceptionMessage)) {
237 exceptionMessage = longMessage;
238 } else if (!exceptionMessage.contains(longMessage)) {
239 exceptionMessage = join(exceptionMessage, System.lineSeparator() + longMessage);
240 }
241 }
242 }
243
244 if (exceptionMessage == null || exceptionMessage.isEmpty()) {
245 exceptionMessage = t.getClass().getSimpleName();
246 }
247
248 if (t instanceof UnknownHostException && !fullMessage.contains("host")) {
249 fullMessage = join(fullMessage, "Unknown host " + exceptionMessage);
250 } else if (!fullMessage.contains(exceptionMessage)) {
251 fullMessage = join(fullMessage, exceptionMessage);
252 }
253 }
254
255 return fullMessage.trim();
256 }
257
258 private String join(String message1, String message2) {
259 String message = "";
260
261 if (message1 != null && !message1.isEmpty()) {
262 message = message1.trim();
263 }
264
265 if (message2 != null && !message2.isEmpty()) {
266 if (message != null && !message.isEmpty()) {
267 if (message.endsWith(".") || message.endsWith("!") || message.endsWith(":")) {
268 message += " ";
269 } else {
270 message += ": ";
271 }
272 }
273
274 message += message2;
275 }
276
277 return message;
278 }
279 }