Skip to content

Commit e324fcc

Browse files
committed
Merge pull request androidannotations#618 from excilys/613_EnhancedCrashReport
613 enhanced crash report
2 parents 12a2dbd + 65590d4 commit e324fcc

9 files changed

Lines changed: 215 additions & 25 deletions

File tree

‎AndroidAnnotations/androidannotations/.settings/org.eclipse.core.resources.prefs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ eclipse.preferences.version=1
22
encoding//src/main/java=UTF-8
33
encoding//src/main/java/rebel.xml=UTF-8
44
encoding//src/main/resources=UTF-8
5+
encoding//src/main/resources/androidannotations-version.properties=utf-8
56
encoding//src/main/resources/rebel.xml=UTF-8
67
encoding//src/test/java=UTF-8
78
encoding//src/test/resources=UTF-8

‎AndroidAnnotations/androidannotations/pom.xml‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,16 @@
7777
</execution>
7878
</executions>
7979
</plugin>
80+
<plugin>
81+
<groupId>org.apache.maven.plugins</groupId>
82+
<artifactId>maven-resources-plugin</artifactId>
83+
<version>2.5</version>
84+
<configuration>
85+
<encoding>${project.build.sourceEncoding}</encoding>
86+
</configuration>
87+
</plugin>
8088
</plugins>
89+
8190
<resources>
8291
<resource>
8392
<directory>src/main/resources</directory>
@@ -88,7 +97,14 @@
8897
<resource>
8998
<directory>src/main/java</directory>
9099
<includes>
91-
<include>org/androidannotations/api/**</include>
100+
<include>org/androidannotations/api/**</include>
101+
</includes>
102+
</resource>
103+
<resource>
104+
<directory>src/main/resources</directory>
105+
<filtering>true</filtering>
106+
<includes>
107+
<include>**/*.properties</include>
92108
</includes>
93109
</resource>
94110
</resources>

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/AndroidAnnotationProcessor.java‎

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
import static org.androidannotations.rclass.ProjectRClassFinder.RESOURCE_PACKAGE_NAME_OPTION;
2323

2424
import java.io.IOException;
25-
import java.io.PrintWriter;
26-
import java.io.StringWriter;
25+
import java.net.URL;
2726
import java.util.Collections;
2827
import java.util.HashSet;
2928
import java.util.Map;
29+
import java.util.Properties;
3030
import java.util.Set;
3131

3232
import javax.annotation.processing.AbstractProcessor;
@@ -121,9 +121,11 @@
121121
import org.androidannotations.annotations.rest.RestService;
122122
import org.androidannotations.annotations.sharedpreferences.Pref;
123123
import org.androidannotations.annotations.sharedpreferences.SharedPref;
124+
import org.androidannotations.exception.ProcessingException;
124125
import org.androidannotations.generation.CodeModelGenerator;
125126
import org.androidannotations.helper.AndroidManifest;
126127
import org.androidannotations.helper.AndroidManifestFinder;
128+
import org.androidannotations.helper.ErrorHelper;
127129
import org.androidannotations.helper.Option;
128130
import org.androidannotations.helper.TimeStats;
129131
import org.androidannotations.model.AndroidRes;
@@ -276,7 +278,10 @@
276278
@SupportedOptions({ TRACE_OPTION, ANDROID_MANIFEST_FILE_OPTION, RESOURCE_PACKAGE_NAME_OPTION })
277279
public class AndroidAnnotationProcessor extends AbstractProcessor {
278280

281+
private final Properties properties = new Properties();
279282
private final TimeStats timeStats = new TimeStats();
283+
private final ErrorHelper errorHelper = new ErrorHelper();
284+
280285
private Set<String> supportedAnnotationNames;
281286

282287
@Override
@@ -285,6 +290,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
285290

286291
Messager messager = processingEnv.getMessager();
287292

293+
loadPropertyFile();
294+
288295
timeStats.setMessager(messager);
289296

290297
messager.printMessage(Diagnostic.Kind.NOTE, "Starting AndroidAnnotations annotation processing");
@@ -296,16 +303,34 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
296303
timeStats.start("Whole Processing");
297304
try {
298305
processThrowing(annotations, roundEnv);
299-
} catch (Exception e) {
306+
} catch (ProcessingException e) {
300307
handleException(annotations, roundEnv, e);
308+
} catch (Exception e) {
309+
handleException(annotations, roundEnv, new ProcessingException(e, null));
301310
}
302311
timeStats.stop("Whole Processing");
303312
timeStats.logStats();
304313
return true;
305314
}
306315

307-
private void processThrowing(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws Exception {
316+
private void loadPropertyFile() {
317+
String filename = "androidannotations-version.properties";
318+
try {
319+
URL url = getClass().getClassLoader().getResource(filename);
320+
properties.load(url.openStream());
321+
} catch (Exception e) {
322+
e.printStackTrace();
308323

324+
Messager messager = processingEnv.getMessager();
325+
messager.printMessage(Diagnostic.Kind.NOTE, "AndroidAnnotations processing failed because " + filename + " couldn't be parsed : " + e.getLocalizedMessage());
326+
}
327+
}
328+
329+
private String getAAProcessorVersion() {
330+
return properties.getProperty("version", "3.0+");
331+
}
332+
333+
private void processThrowing(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws ProcessingException, Exception {
309334
if (nothingToDo(annotations, roundEnv)) {
310335
return;
311336
}
@@ -378,7 +403,7 @@ private Option<IRClass> findRClasses(AndroidManifest androidManifest) throws IOE
378403
return Option.of(coumpoundRClass);
379404
}
380405

381-
private AnnotationElements validateAnnotations(AnnotationElementsHolder extractedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) {
406+
private AnnotationElements validateAnnotations(AnnotationElementsHolder extractedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws ProcessingException, Exception {
382407
timeStats.start("Validate Annotations");
383408
ModelValidator modelValidator = buildModelValidator(rClass, androidSystemServices, androidManifest);
384409
AnnotationElements validatedAnnotations = modelValidator.validate(extractedModel);
@@ -475,7 +500,7 @@ private boolean traceActivated() {
475500
}
476501
}
477502

478-
private ProcessResult processAnnotations(AnnotationElements validatedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws Exception {
503+
private ProcessResult processAnnotations(AnnotationElements validatedModel, IRClass rClass, AndroidSystemServices androidSystemServices, AndroidManifest androidManifest) throws ProcessingException, Exception {
479504
timeStats.start("Process Annotations");
480505
ModelProcessor modelProcessor = buildModelProcessor(rClass, androidSystemServices, androidManifest, validatedModel);
481506
ProcessResult processResult = modelProcessor.process(validatedModel);
@@ -567,13 +592,13 @@ private void generateSources(ProcessResult processResult) throws IOException {
567592
timeStats.start("Generate Sources");
568593
Messager messager = processingEnv.getMessager();
569594
messager.printMessage(Diagnostic.Kind.NOTE, "Number of files generated by AndroidAnnotations: " + processResult.codeModel.countArtifacts());
570-
CodeModelGenerator modelGenerator = new CodeModelGenerator(processingEnv.getFiler(), messager);
595+
CodeModelGenerator modelGenerator = new CodeModelGenerator(processingEnv.getFiler(), messager, getAAProcessorVersion());
571596
modelGenerator.generate(processResult);
572597
timeStats.stop("Generate Sources");
573598
}
574599

575-
private void handleException(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv, Exception e) {
576-
String errorMessage = "Unexpected error. Please report an issue on AndroidAnnotations, with the following content: " + stackTraceToString(e);
600+
private void handleException(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv, ProcessingException e) {
601+
String errorMessage = errorHelper.getErrorMessage(processingEnv, e, getAAProcessorVersion());
577602

578603
Messager messager = processingEnv.getMessager();
579604
messager.printMessage(Diagnostic.Kind.ERROR, errorMessage);
@@ -588,13 +613,6 @@ private void handleException(Set<? extends TypeElement> annotations, RoundEnviro
588613
messager.printMessage(Diagnostic.Kind.ERROR, errorMessage, element);
589614
}
590615

591-
private String stackTraceToString(Throwable e) {
592-
StringWriter writer = new StringWriter();
593-
PrintWriter pw = new PrintWriter(writer);
594-
e.printStackTrace(pw);
595-
return writer.toString();
596-
}
597-
598616
@Override
599617
public Set<String> getSupportedAnnotationTypes() {
600618
if (supportedAnnotationNames == null) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.androidannotations.exception;
2+
3+
import javax.lang.model.element.Element;
4+
5+
public class ProcessingException extends Exception {
6+
7+
private static final long serialVersionUID = -1282996599471872615L;
8+
9+
private Element element;
10+
11+
public ProcessingException(Throwable cause, Element element) {
12+
super(cause);
13+
this.element = element;
14+
}
15+
16+
public ProcessingException(String message, Throwable cause, Element element) {
17+
super(message, cause);
18+
this.element = element;
19+
}
20+
21+
public Element getElement() {
22+
return element;
23+
}
24+
25+
}

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/generation/CodeModelGenerator.java‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ public class CodeModelGenerator {
2828

2929
private final Filer filer;
3030
private final Messager messager;
31+
private final String aaVersion;
3132

32-
public CodeModelGenerator(Filer filer, Messager messager) {
33+
public CodeModelGenerator(Filer filer, Messager messager, String aaVersion) {
3334
this.filer = filer;
3435
this.messager = messager;
36+
this.aaVersion = aaVersion;
3537
}
3638

3739
public void generate(ProcessResult processResult) throws IOException {
@@ -41,7 +43,7 @@ public void generate(ProcessResult processResult) throws IOException {
4143

4244
SourceCodewriter sourceCodeWriter = new SourceCodewriter(filer, messager, processResult.originatingElements);
4345

44-
PrologCodeWriter prologCodeWriter = new PrologCodeWriter(sourceCodeWriter, "DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING AndroidAnnotations.\n");
46+
PrologCodeWriter prologCodeWriter = new PrologCodeWriter(sourceCodeWriter, "DO NOT EDIT THIS FILE, IT HAS BEEN GENERATED USING AndroidAnnotations " + aaVersion + ".\n");
4547

4648
processResult.codeModel.build(prologCodeWriter, new ResourceCodeWriter(filer));
4749
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package org.androidannotations.helper;
2+
3+
import java.io.BufferedReader;
4+
import java.io.CharArrayWriter;
5+
import java.io.IOException;
6+
import java.io.InputStreamReader;
7+
import java.io.PrintWriter;
8+
import java.io.StringWriter;
9+
import java.io.UnsupportedEncodingException;
10+
import java.net.URLEncoder;
11+
import java.util.Map;
12+
import java.util.Map.Entry;
13+
import java.util.Set;
14+
15+
import javax.annotation.processing.ProcessingEnvironment;
16+
import javax.lang.model.element.Element;
17+
import javax.lang.model.util.Elements;
18+
19+
import org.androidannotations.exception.ProcessingException;
20+
21+
public class ErrorHelper {
22+
23+
public String getErrorMessage(ProcessingEnvironment processingEnv, ProcessingException e, String aaVersion) {
24+
String errorMessage = "Unexpected error in AndroidAnnotations " + aaVersion + "!\n" //
25+
+ "You should check if there is already an issue about it on https://github.com/excilys/androidannotations/search?q=" + urlEncodedErrorMessage(e) + "&type=Issues\n" //
26+
+ "If none exists, please open a new one with the following content and tell us if you can reproduce it or not. Don't forget to give us as much information as you can (like parts of your code in failure).\n";
27+
errorMessage += "Java version: " + getJavaCompilerVersion() + "\n";
28+
errorMessage += "Javac processors options: " + annotationProcessorOptions(processingEnv) + "\n";
29+
errorMessage += "Stacktrace: " + stackTraceToString(e.getCause());
30+
31+
Element element = e.getElement();
32+
if (element != null) {
33+
errorMessage += "Thrown from: " + elementContainer(element) + "\n";
34+
errorMessage += "Element (" + element.getClass().getSimpleName() + "): " + elementFullString(processingEnv, element) + "\n";
35+
}
36+
37+
return errorMessage;
38+
}
39+
40+
private String elementFullString(ProcessingEnvironment processingEnv, Element element) {
41+
Elements elementUtils = processingEnv.getElementUtils();
42+
CharArrayWriter writer = new CharArrayWriter();
43+
elementUtils.printElements(writer, element);
44+
return writer.toString();
45+
}
46+
47+
private String elementContainer(Element element) {
48+
Element enclosingElement = element.getEnclosingElement();
49+
return enclosingElement != null ? enclosingElement.toString() : "";
50+
}
51+
52+
private String annotationProcessorOptions(ProcessingEnvironment processingEnv) {
53+
Map<String, String> options = processingEnv.getOptions();
54+
Set<Entry<String, String>> optionsEntries = options.entrySet();
55+
56+
String result = "";
57+
for (Entry<String, String> optionEntry : optionsEntries) {
58+
result += optionEntry.getKey() + "=" + optionEntry.getValue() + ", ";
59+
}
60+
return result.length() > 2 ? result.substring(0, result.length() - 2) : result;
61+
}
62+
63+
private String getJavaCompilerVersion() {
64+
ProcessBuilder pb = new ProcessBuilder("javac", "-version");
65+
pb.redirectErrorStream(true);
66+
67+
BufferedReader in = null;
68+
try {
69+
Process process = pb.start();
70+
in = new BufferedReader(new InputStreamReader(process.getInputStream()));
71+
String buffer = in.readLine();
72+
process.waitFor();
73+
return buffer;
74+
} catch (Exception e) {
75+
} finally {
76+
if (in != null) {
77+
try {
78+
in.close();
79+
} catch (IOException e) {
80+
}
81+
}
82+
}
83+
return "unknown";
84+
}
85+
86+
private String urlEncodedErrorMessage(Throwable e) {
87+
try {
88+
return URLEncoder.encode(e.getCause().getClass().getName(), "UTF-8");
89+
} catch (UnsupportedEncodingException e1) {
90+
return "";
91+
}
92+
}
93+
94+
private String stackTraceToString(Throwable e) {
95+
StringWriter writer = new StringWriter();
96+
PrintWriter pw = new PrintWriter(writer);
97+
e.printStackTrace(pw);
98+
return writer.toString();
99+
}
100+
101+
}

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/ModelProcessor.java‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import javax.lang.model.element.Modifier;
2525
import javax.lang.model.element.TypeElement;
2626

27+
import org.androidannotations.exception.ProcessingException;
2728
import org.androidannotations.model.AnnotationElements;
2829
import org.androidannotations.model.AnnotationElements.AnnotatedAndRootElements;
2930

@@ -59,7 +60,7 @@ public void register(GeneratingElementProcessor processor) {
5960
typeProcessors.add(processor);
6061
}
6162

62-
public ProcessResult process(AnnotationElements validatedModel) throws Exception {
63+
public ProcessResult process(AnnotationElements validatedModel) throws ProcessingException, Exception {
6364

6465
JCodeModel codeModel = new JCodeModel();
6566

@@ -75,7 +76,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
7576
* extend them).
7677
*/
7778
if (!isAbstractClass(annotatedElement)) {
78-
processor.process(annotatedElement, codeModel, eBeansHolder);
79+
processThrowing(processor, annotatedElement, codeModel, eBeansHolder);
7980
}
8081
}
8182
/*
@@ -99,7 +100,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
99100
* elements that are not validated, and therefore not available.
100101
*/
101102
if (holder != null) {
102-
processor.process(elements.annotatedElement, codeModel, holder);
103+
processThrowing(processor, elements.annotatedElement, codeModel, holder);
103104
}
104105
}
105106

@@ -120,7 +121,7 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
120121
*/
121122
if (!isAbstractClass(enclosingElement)) {
122123
EBeanHolder holder = eBeansHolder.getEBeanHolder(enclosingElement);
123-
processor.process(annotatedElement, codeModel, holder);
124+
processThrowing(processor, annotatedElement, codeModel, holder);
124125
}
125126
}
126127

@@ -132,6 +133,22 @@ public ProcessResult process(AnnotationElements validatedModel) throws Exception
132133
eBeansHolder.getApiClassesToGenerate());
133134
}
134135

136+
private void processThrowing(GeneratingElementProcessor processor, Element element, JCodeModel codeModel, EBeansHolder eBeansHolder) throws Exception, ProcessingException {
137+
try {
138+
processor.process(element, codeModel, eBeansHolder);
139+
} catch (Exception e) {
140+
throw new ProcessingException(e, element);
141+
}
142+
}
143+
144+
private void processThrowing(DecoratingElementProcessor processor, Element element, JCodeModel codeModel, EBeanHolder eBeanHolder) throws Exception, ProcessingException {
145+
try {
146+
processor.process(element, codeModel, eBeanHolder);
147+
} catch (Exception e) {
148+
throw new ProcessingException(e, element);
149+
}
150+
}
151+
135152
private boolean isAbstractClass(Element annotatedElement) {
136153
if (annotatedElement instanceof TypeElement) {
137154
TypeElement typeElement = (TypeElement) annotatedElement;

0 commit comments

Comments
 (0)