Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8031122

Annotation processors may be exposed with syntactically invalid annotations

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • 8
    • 7u40
    • tools
    • None
    • JDK 7u40, Linux x86_64

      Found this in my own annotation processor.

      Let's define these three classes first:

      ---- MyAnnotation.java ----
      public @interface MyAnnotation {
         String value();
      }

      ---- MyClass.java ----
      @MyAnnotation
      public class MyClass {
      }

      ---- MyProcessor.java ----
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedSourceVersion;

      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Collections;
      import java.util.HashMap;
      import java.util.HashSet;
      import java.util.LinkedHashSet;
      import java.util.List;
      import java.util.Map;
      import java.util.Set;

      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;

      import javax.tools.Diagnostic.Kind;

      @SupportedSourceVersion(SourceVersion.RELEASE_6)
      public class MyProcessor extends AbstractProcessor {

          @Override
          public Set<String> getSupportedAnnotationTypes() {
              return Collections.singleton(MyAnnotation.class.getName());
          }

          @Override
          public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
              for (TypeElement annotation : annotations) {
                  for (Element method : roundEnv.getElementsAnnotatedWith(annotation)) {
                      method.getAnnotation(MyAnnotation.class).value(); // throws IncompleteAnnotationException
                  }
              }
              return true;
          }
      }

      This the sequence of action exposing the issue:

      1. Compile the processor first:

      $ javac MyProcessor.java

      2. Compile "user" classes without annotation processor, javac fails with reasonable message telling user to supply the value():

      $ javac MyAnnotation.java MyClass.java
      MyClass.java:1: error: annotation MyAnnotation is missing value for the attribute value
      @MyAnnotation
      ^
      1 error

      3. Now do the same, but with annotation processor on board:

      $ javac MyAnnotation.java MyClass.java -processor MyProcessor
      An annotation processor threw an uncaught exception.
      Consult the following stack trace for details.
      java.lang.annotation.IncompleteAnnotationException: MyAnnotation missing element value
      at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:72)
      at com.sun.proxy.$Proxy4.value(Unknown Source)
      at MyProcessor.process(MyProcessor.java:33)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:793)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:722)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
      at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
      at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
      at com.sun.tools.javac.main.Main.compile(Main.java:439)
      at com.sun.tools.javac.main.Main.compile(Main.java:353)
      at com.sun.tools.javac.main.Main.compile(Main.java:342)
      at com.sun.tools.javac.main.Main.compile(Main.java:333)
      at com.sun.tools.javac.Main.compile(Main.java:76)
      at com.sun.tools.javac.Main.main(Main.java:61)

      BAM! Exception with uber-stacktrace in your head. That means annotation processor got exposed with the incomplete annotation, but before javac could tell user what is wrong?

      The most troubling part is that there is no sane API in annotation processor to catch this kind of behavior, except for catching the exception and moving on with printing the exception of its own. My expectation would be, however, that the syntax/semantics checks for the existing classes should be done before exposing them for further processing.

            jlahoda Jan Lahoda
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: