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

AnnotationTypeMismatchException in javac with annotation processing

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10 Pro

      A DESCRIPTION OF THE PROBLEM :
      When first compiling two interdependent annotation classes and an annotation processor and then in the second step a class bearing one of the annotations the processor is focusing on, using same processor for annotation processing during javac compilation, the following exception appears:

      ...
      An annotation processor threw an uncaught exception.
      Consult the following stack trace for details.
      java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract org.example.MySecondAnnotation org.example.MyFirstAnnotation.secondAnnotation() (Found data of type org.example.MySecondAnnotation)
      ...

      This works on JDK 8 and to some extent in 11 (with default target 11, not with '--release 8') and not at all in 17 and 21.

      REGRESSION : Last worked in version 8

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      On JDKs 17, 21 (same works on 8, 11):
      $ javac org/example/MyFirstAnnotation.java org/example/MySecondAnnotation.java org/example/Processor.java
      $ javac -processor org.example.Processor -cp . org/example/AnnotatedClass.java

      On JDK 11:
      $ javac --release 8 org/example/MyFirstAnnotation.java org/example/MySecondAnnotation.java org/example/Processor.java
      $ javac --release 8 -processor org.example.Processor -cp . org/example/AnnotatedClass.java


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Compilation works, second command prints:

      Processor ran!
      [org.example.MyFirstAnnotation]
      [errorRaised=false, rootElements=[org.example.AnnotatedClass], processingOver=false]
      @org.example.MyFirstAnnotation(secondAnnotation=@org.example.MySecondAnnotation(stringArray={""})) -> @org.example.MySecondAnnotation(stringArray={""})
      warning: No SupportedSourceVersion annotation found on org.example.Processor, returning RELEASE_6.
      warning: Supported source version 'RELEASE_6' from annotation processor 'org.example.Processor' less than -source '11'
      Processor ran!
      []
      [errorRaised=false, rootElements=[], processingOver=true]
      2 warnings

      ACTUAL -
      Processor ran!
      [org.example.MyFirstAnnotation]
      [errorRaised=false, rootElements=[org.example.AnnotatedClass], processingOver=false]
      warning: No SupportedSourceVersion annotation found on org.example.Processor, returning RELEASE_6.
      warning: Supported source version 'RELEASE_6' from annotation processor 'org.example.Processor' less than -source '17'
      2 warnings


      An annotation processor threw an uncaught exception.
      Consult the following stack trace for details.
      java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract org.example.MySecondAnnotation org.example.MyFirstAnnotation.secondAnnotation() (Found data of type org.example.MySecondAnnotation)
              at jdk.compiler/com.sun.tools.javac.model.AnnotationProxyMaker$ValueVisitor$1AnnotationTypeMismatchExceptionProxy.generateException(AnnotationProxyMaker.java:271)
              at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:89)
              at jdk.proxy3/jdk.proxy3.$Proxy3.secondAnnotation(Unknown Source)
              at org.example.Processor.process(Processor.java:23)
              at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:1023)
              at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:939)
              at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1267)
              at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1382)
              at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1234)
              at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:916)
              at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)
              at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
              at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)
              at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)


      ---------- BEGIN SOURCE ----------
      package org.example;

      public @interface MyFirstAnnotation {
          MySecondAnnotation secondAnnotation() default @MySecondAnnotation;//(stringArray = "");
      }

      ------------------------------------------------------------------------

      package org.example;

      public @interface MySecondAnnotation {
          String[] stringArray() default "";
      }

      ------------------------------------------------------------------------

      package org.example;

      import java.util.Set;

      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;

      @SupportedAnnotationTypes("org.example.MyFirstAnnotation")
      public class Processor extends AbstractProcessor {

          public boolean process(final Set<? extends TypeElement> annotations,
                                 final RoundEnvironment roundEnv) {

              System.out.println("Processor ran!");
              System.out.println(annotations);
              System.out.println(roundEnv);

              for (Element element : roundEnv.getElementsAnnotatedWith(MyFirstAnnotation.class)) {
                  MyFirstAnnotation firstAnnotation = element.getAnnotation(MyFirstAnnotation.class);
                  MySecondAnnotation secondAnnotation = firstAnnotation.secondAnnotation();
                  System.out.println(firstAnnotation + " -> " + secondAnnotation);
              }
              return true;
          }
      }

      ------------------------------------------------------------------------

      package org.example;

      /*
       * Uncomment one of these lines and the annotation processor starts working.
       */

      //import org.example.MySecondAnnotation;
      @MyFirstAnnotation(
              //secondAnnotation = @MySecondAnnotation
      )
      public class AnnotatedClass {
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Either of the following works:

      1.) In AnnotatedClass, change @MyFirstAnnotation to @MyFirstAnnotation(secondAnnotation = @MySecondAnnotation)

      2.) In AnnotatedClass, redundantly import org.example.MySecondAnnotation

      3.) In MyFirstAnnotation, change the default from @MySecondAnnotation to @MySecondAnnotation(stringArray = "")

      FREQUENCY : always


            vromero Vicente Arturo Romero Zaldivar
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: