1 package org.apache.maven.exception;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.net.ConnectException;
24 import java.net.UnknownHostException;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import javax.inject.Named;
29 import javax.inject.Singleton;
30
31 import org.apache.maven.lifecycle.LifecycleExecutionException;
32 import org.apache.maven.model.building.ModelProblem;
33 import org.apache.maven.model.building.ModelProblemUtils;
34 import org.apache.maven.plugin.AbstractMojoExecutionException;
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugin.MojoFailureException;
37 import org.apache.maven.plugin.PluginContainerException;
38 import org.apache.maven.plugin.PluginExecutionException;
39 import org.apache.maven.project.ProjectBuildingException;
40 import org.apache.maven.project.ProjectBuildingResult;
41 import org.codehaus.plexus.util.StringUtils;
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
90
91 @Named
92 @Singleton
93 public class DefaultExceptionHandler
94 implements ExceptionHandler
95 {
96
97 public ExceptionSummary handleException( Throwable exception )
98 {
99 return handle( "", exception );
100 }
101
102 private ExceptionSummary handle( String message, Throwable exception )
103 {
104 String reference = getReference( exception );
105
106 List<ExceptionSummary> children = null;
107
108 if ( exception instanceof ProjectBuildingException )
109 {
110 List<ProjectBuildingResult> results = ( (ProjectBuildingException) exception ).getResults();
111
112 children = new ArrayList<>();
113
114 for ( ProjectBuildingResult result : results )
115 {
116 ExceptionSummary child = handle( result );
117 if ( child != null )
118 {
119 children.add( child );
120 }
121 }
122
123 message = "The build could not read " + children.size() + " project" + ( children.size() == 1 ? "" : "s" );
124 }
125 else
126 {
127 message = getMessage( message, exception );
128 }
129
130 return new ExceptionSummary( exception, message, reference, children );
131 }
132
133 private ExceptionSummary handle( ProjectBuildingResult result )
134 {
135 List<ExceptionSummary> children = new ArrayList<>();
136
137 for ( ModelProblem problem : result.getProblems() )
138 {
139 ExceptionSummary child = handle( problem, result.getProjectId() );
140 if ( child != null )
141 {
142 children.add( child );
143 }
144 }
145
146 if ( children.isEmpty() )
147 {
148 return null;
149 }
150
151 String message = System.lineSeparator()
152 + "The project " + ( result.getProjectId().isEmpty() ? "" : result.getProjectId() + " " )
153 + "(" + result.getPomFile() + ") has "
154 + children.size() + " error" + ( children.size() == 1 ? "" : "s" );
155
156 return new ExceptionSummary( null, message, null, children );
157 }
158
159 private ExceptionSummary handle( ModelProblem problem, String projectId )
160 {
161 if ( ModelProblem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
162 {
163 String message = problem.getMessage();
164
165 String location = ModelProblemUtils.formatLocation( problem, projectId );
166
167 if ( !location.isEmpty() )
168 {
169 message += " @ " + location;
170 }
171
172 return handle( message, problem.getException() );
173 }
174 else
175 {
176 return null;
177 }
178 }
179
180 private String getReference( Throwable exception )
181 {
182 String reference = "";
183
184 if ( exception != null )
185 {
186 if ( exception instanceof MojoExecutionException )
187 {
188 reference = MojoExecutionException.class.getSimpleName();
189
190 Throwable cause = exception.getCause();
191 if ( cause instanceof IOException )
192 {
193 cause = cause.getCause();
194 if ( cause instanceof ConnectException )
195 {
196 reference = ConnectException.class.getSimpleName();
197 }
198 }
199 }
200 else if ( exception instanceof MojoFailureException )
201 {
202 reference = MojoFailureException.class.getSimpleName();
203 }
204 else if ( exception instanceof LinkageError )
205 {
206 reference = LinkageError.class.getSimpleName();
207 }
208 else if ( exception instanceof PluginExecutionException )
209 {
210 Throwable cause = exception.getCause();
211
212 if ( cause instanceof PluginContainerException )
213 {
214 Throwable cause2 = cause.getCause();
215
216 if ( cause2 instanceof NoClassDefFoundError )
217 {
218 String message = cause2.getMessage();
219 if ( message != null && message.contains( "org/sonatype/aether/" ) )
220 {
221 reference = "AetherClassNotFound";
222 }
223 }
224 }
225
226 if ( StringUtils.isEmpty( reference ) )
227 {
228 reference = getReference( cause );
229 }
230
231 if ( StringUtils.isEmpty( reference ) )
232 {
233 reference = exception.getClass().getSimpleName();
234 }
235 }
236 else if ( exception instanceof LifecycleExecutionException )
237 {
238 reference = getReference( exception.getCause() );
239 }
240 else if ( isNoteworthyException( exception ) )
241 {
242 reference = exception.getClass().getSimpleName();
243 }
244 }
245
246 if ( StringUtils.isNotEmpty( reference ) && !reference.startsWith( "http:" ) )
247 {
248 reference = "http://cwiki.apache.org/confluence/display/MAVEN/" + reference;
249 }
250
251 return reference;
252 }
253
254 private boolean isNoteworthyException( Throwable exception )
255 {
256 if ( exception == null )
257 {
258 return false;
259 }
260 else if ( exception instanceof Error )
261 {
262 return true;
263 }
264 else if ( exception instanceof RuntimeException )
265 {
266 return false;
267 }
268 else
269 {
270 return !exception.getClass().getName().startsWith( "java" );
271 }
272 }
273
274 private String getMessage( String message, Throwable exception )
275 {
276 String fullMessage = ( message != null ) ? message : "";
277
278 for ( Throwable t = exception; t != null; t = t.getCause() )
279 {
280 String exceptionMessage = t.getMessage();
281
282 if ( t instanceof AbstractMojoExecutionException )
283 {
284 String longMessage = ( (AbstractMojoExecutionException) t ).getLongMessage();
285 if ( StringUtils.isNotEmpty( longMessage ) )
286 {
287 if ( StringUtils.isEmpty( exceptionMessage ) || longMessage.contains( exceptionMessage ) )
288 {
289 exceptionMessage = longMessage;
290 }
291 else if ( !exceptionMessage.contains( longMessage ) )
292 {
293 exceptionMessage = join( exceptionMessage, System.lineSeparator() + longMessage );
294 }
295 }
296 }
297
298 if ( StringUtils.isEmpty( exceptionMessage ) )
299 {
300 exceptionMessage = t.getClass().getSimpleName();
301 }
302
303 if ( t instanceof UnknownHostException && !fullMessage.contains( "host" ) )
304 {
305 fullMessage = join( fullMessage, "Unknown host " + exceptionMessage );
306 }
307 else if ( !fullMessage.contains( exceptionMessage ) )
308 {
309 fullMessage = join( fullMessage, exceptionMessage );
310 }
311 }
312
313 return fullMessage.trim();
314 }
315
316 private String join( String message1, String message2 )
317 {
318 String message = "";
319
320 if ( StringUtils.isNotEmpty( message1 ) )
321 {
322 message = message1.trim();
323 }
324
325 if ( StringUtils.isNotEmpty( message2 ) )
326 {
327 if ( StringUtils.isNotEmpty( message ) )
328 {
329 if ( message.endsWith( "." ) || message.endsWith( "!" ) || message.endsWith( ":" ) )
330 {
331 message += " ";
332 }
333 else
334 {
335 message += ": ";
336 }
337 }
338
339 message += message2;
340 }
341
342 return message;
343 }
344
345 }