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

Class.getAnnotatedSuperclass() does not correctly extract annotations

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P4
    • None
    • 8u20, 9
    • core-libs

    Description

      FULL PRODUCT VERSION :
      java version "1.8.0_20"
      Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
      Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      MacOS X 10.9.4
      (uname reports: Darwin Kernel Version 13.3.0)

      A DESCRIPTION OF THE PROBLEM :
      I have not yet tried all of the AnnotatedType-related API, but the first one I reached for, Class.getAnnotatedSuperclass(), does not work.

      It returns AnnotatedType implementations that do not actual return any of the annotations present in the type. Reading the class file shows the type annotations are correctly stored by javac. But they are not accessible via the new reflection API whose sole purpose is to access them.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the program in the "Source code" section below. It contains a class whose "extends" clause uses type annotations, both on the superclass and on the type variables (the superclass is a generic type).



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I would expect output from the program to include information about the type annotations:
      ----
      TypeAnnotationBug.TypeAnnotationBug$X<P1, P2, java.lang.Class<P1>> =>
      @TypeAnnotationBug$A()
      Type Variable P1 =>
      @TypeAnnotationBug$B()
      Type Variable P2 =>
      @TypeAnnotationBug$C()
      Type Variable java.lang.Class<P1> =>
      @TypeAnnotationBug$D()
         Type Variable P1 =>
      @TypeAnnotationBug$E()
      ACTUAL -
      No annotation information seems to be available via clazz.getAnnotatedSuperclass().getAnnotations() nor on the actual type arguments from clazz.getAnnotatedSuperclass().getAnnotatedActualTypeArguments().

      Here is the output I get from the sample program:
      ----
      TypeAnnotationBug.TypeAnnotationBug$X<P1, P2, java.lang.Class<P1>> =>
      Type Variable P1 =>
      Type Variable P2 =>
      Type Variable java.lang.Class<P1> =>
         Type Variable P1 =>

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.lang.annotation.Annotation;
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      import java.lang.reflect.AnnotatedParameterizedType;
      import java.lang.reflect.AnnotatedType;
      import java.lang.reflect.ParameterizedType;
      import java.lang.reflect.Type;

      public class TypeAnnotationBug {
         
         @Target(ElementType.TYPE_USE)
         @Retention(RetentionPolicy.RUNTIME)
         @interface A {
         }

         @Target(ElementType.TYPE_USE)
         @Retention(RetentionPolicy.RUNTIME)
         @interface B {
         }

         @Target(ElementType.TYPE_USE)
         @Retention(RetentionPolicy.RUNTIME)
         @interface C {
         }

         @Target(ElementType.TYPE_USE)
         @Retention(RetentionPolicy.RUNTIME)
         @interface D {
         }

         @Target(ElementType.TYPE_USE)
         @Retention(RetentionPolicy.RUNTIME)
         @interface E {
         }

         static class X<P1, P2, P3> {
         }
         
         static class Y<P1, P2> extends @A X<@B P1, @C P2, @D Class<@E P1>> {
         }

         public static void main(String args[]) {
            AnnotatedType x = Y.class.getAnnotatedSuperclass();
            System.out.println(x.getType().getTypeName() + " => ");
            for (Annotation a : x.getAnnotations()) {
               System.out.println(a);
            }
            AnnotatedParameterizedType xpt = (AnnotatedParameterizedType) x;
            int i = 0;
            for (AnnotatedType arg : xpt.getAnnotatedActualTypeArguments()) {
               Type argType = ((ParameterizedType) xpt.getType()).getActualTypeArguments()[i++];
               System.out.println("Type Variable " + argType.getTypeName() + " => ");
               for (Annotation a : arg.getAnnotations()) {
                  System.out.println(a);
               }
               if (arg instanceof AnnotatedParameterizedType) {
                  int j = 0;
                  for (AnnotatedType nestedArg : ((AnnotatedParameterizedType) arg).getAnnotatedActualTypeArguments()) {
                     Type nestedArgType = ((ParameterizedType) arg.getType()).getActualTypeArguments()[j++];
                     System.out.println(" Type Variable " + nestedArgType.getTypeName() + " => ");
                     for (Annotation a : nestedArg.getAnnotations()) {
                        System.out.println(a);
                     }
                  }
               }
            }
         }
      }

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

      Attachments

        Issue Links

          Activity

            People

              jfranck Joel Borggrén-Franck (Inactive)
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: