From fbb80bfb251e4f56f44b881b6d6763d9e1c56573 Mon Sep 17 00:00:00 2001 From: Andreas Gudian Date: Mon, 18 May 2015 21:04:22 +0200 Subject: [PATCH] #455 Add a fallback error reporting in case any uncaught exceptions occur - otherwise those errors are just swallowed and hard to find --- .../org/mapstruct/ap/MappingProcessor.java | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java index 4938bd804..096727e83 100644 --- a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java @@ -18,6 +18,8 @@ */ package org.mapstruct.ap; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -136,28 +138,53 @@ public class MappingProcessor extends AbstractProcessor { continue; } - for ( Element mapperElement : roundEnvironment.getElementsAnnotatedWith( annotation ) ) { - TypeElement mapperTypeElement = asTypeElement( mapperElement ); + Set elementsWithAnnotation; + try { + elementsWithAnnotation = roundEnvironment.getElementsAnnotatedWith( annotation ); + } + catch ( Throwable t ) { // whenever that may happen, but just to stay on the save side + handleUncaughtError( annotation, t ); + continue; + } - // on some JDKs, RoundEnvironment.getElementsAnnotatedWith( ... ) returns types with - // annotations unknown to the compiler, even though they are not declared Mappers - if ( mapperTypeElement == null || MapperPrism.getInstanceOn( mapperTypeElement ) == null ) { - continue; + for ( Element mapperElement : elementsWithAnnotation ) { + try { + TypeElement mapperTypeElement = asTypeElement( mapperElement ); + + // on some JDKs, RoundEnvironment.getElementsAnnotatedWith( ... ) returns types with + // annotations unknown to the compiler, even though they are not declared Mappers + if ( mapperTypeElement == null || MapperPrism.getInstanceOn( mapperTypeElement ) == null ) { + continue; + } + + // create a new context for each generated mapper in order to have imports of referenced types + // correctly managed; + // note that this assumes that a new source file is created for each mapper which must not + // necessarily be the case, e.g. in case of several mapper interfaces declared as inner types + // of one outer interface + ProcessorContext context = new DefaultModelElementProcessorContext( processingEnv, options ); + processMapperTypeElement( context, mapperTypeElement ); + } + catch ( Throwable t ) { + handleUncaughtError( mapperElement, t ); + break; } - - // create a new context for each generated mapper in order to have imports of referenced types - // correctly managed; - // note that this assumes that a new source file is created for each mapper which must not - // necessarily be the case, e.g. in case of several mapper interfaces declared as inner types - // of one outer interface - ProcessorContext context = new DefaultModelElementProcessorContext( processingEnv, options ); - processMapperTypeElement( context, mapperTypeElement ); } } return ANNOTATIONS_CLAIMED_EXCLUSIVELY; } + private void handleUncaughtError(Element element, Throwable thrown) { + StringWriter sw = new StringWriter(); + thrown.printStackTrace( new PrintWriter( sw ) ); + + String reportableStacktrace = sw.toString().replace( System.getProperty( "line.separator" ), " " ); + + processingEnv.getMessager().printMessage( + Kind.ERROR, "Internal error in the mapping processor: " + reportableStacktrace, element ); + } + /** * Applies all registered {@link ModelElementProcessor}s to the given mapper * type.