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

Element#getAnnotation throws ClassCastException on unresolvable symbol

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 7, 8, 9
    • tools
    • x86_64
    • linux

      FULL PRODUCT VERSION :
      java version "1.9.0-ea"
      Java(TM) SE Runtime Environment (build 1.9.0-ea-b82)
      Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b82, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      I have an annotation that has a value that is an array of Classes. I use that annotation in another class, but with a class that is not resolvable. Finally, I have an annotation processor that calls Element#getAnnotation on the annotated element. When I compile the test class with my annotation processor running, javac crashes with a ClassCastException (see full output below).

      ADDITIONAL REGRESSION INFORMATION:
      I've confirmed that this crash occurs in javac 7, 8, and 9.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      From the source code section below, put the code into the named files. Then:

      $ javac ReproProcessor.java MyAnnotation.java
      $ javac -processor ReproProcessor TestClass.java

      You'll get the crash and the stack trace I pasted below.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      javac reports a "cannot find symbol" error but does not crash.
      ACTUAL -
      javac crashes.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      TestClass.java:2: error: cannot find symbol
        @MyAnnotation(classes = {ClassThatDoesNotExist.class})
                                 ^
        symbol: class ClassThatDoesNotExist
        location: class TestClass
      warning: Supported source version 'RELEASE_7' from annotation processor 'ReproProcessor' less than -source '1.9'
      1 error
      1 warning


      An annotation processor threw an uncaught exception.
      Consult the following stack trace for details.
      java.lang.ClassCastException: com.sun.tools.javac.code.Attribute$UnresolvedClass cannot be cast to com.sun.tools.javac.code.Attribute$Class
      at com.sun.tools.javac.model.AnnotationProxyMaker$ValueVisitor.visitArray(AnnotationProxyMaker.java:192)
      at com.sun.tools.javac.code.Attribute$Array.accept(Attribute.java:327)
      at com.sun.tools.javac.model.AnnotationProxyMaker$ValueVisitor.getValue(AnnotationProxyMaker.java:167)
      at com.sun.tools.javac.model.AnnotationProxyMaker.generateValue(AnnotationProxyMaker.java:145)
      at com.sun.tools.javac.model.AnnotationProxyMaker.getAllReflectedValues(AnnotationProxyMaker.java:104)
      at com.sun.tools.javac.model.AnnotationProxyMaker.generateAnnotation(AnnotationProxyMaker.java:90)
      at com.sun.tools.javac.model.AnnotationProxyMaker.generateAnnotation(AnnotationProxyMaker.java:81)
      at com.sun.tools.javac.code.AnnoConstruct.getAnnotation(AnnoConstruct.java:184)
      at ReproProcessor.process(ReproProcessor.java:13)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:827)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:739)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2000(JavacProcessingEnvironment.java:97)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1047)
      at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1154)
      at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1150)
      at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:838)
      at com.sun.tools.javac.main.Main.compile(Main.java:254)
      at com.sun.tools.javac.main.Main.compile(Main.java:142)
      at com.sun.tools.javac.Main.compile(Main.java:56)
      at com.sun.tools.javac.Main.main(Main.java:42)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      MyAnnotation.java:
      public @interface MyAnnotation {
        Class<?>[] classes() default {};
      }

      ReproProcessor.java:
      import javax.annotation.processing.*;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.*;
      import java.util.Set;

      @SupportedAnnotationTypes("MyAnnotation")
      @SupportedSourceVersion(SourceVersion.RELEASE_7)
      public class ReproProcessor extends AbstractProcessor {
        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
          Set<? extends Element> elems = roundEnv.getElementsAnnotatedWith(MyAnnotation.class);
          for (Element elem : elems) {
            System.out.println(elem.getAnnotation(MyAnnotation.class));
          }

          return false;
        }
      }

      TestClass.java:
      public class TestClass {
        @MyAnnotation(classes = {ClassThatDoesNotExist.class})
        public void foo() {}
      }
      ---------- END SOURCE ----------

            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: