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

Example of wrong type annotation indexing of type varaible bounds on recursive type

    XMLWordPrintable

    Details

      Description

      FULL PRODUCT VERSION :


      A DESCRIPTION OF THE PROBLEM :
      Type annotations on type variable bounds are not always resolved correctly by the Java core reflection API if the bound is put on a parameterized type that is not an interface type or on another type variable.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      true
      true
      true
      true
      true
      ACTUAL -
      false
      true
      true
      true
      false

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      import java.util.ArrayList;
      import java.util.List;

      public class Foo<T,
              S extends @Sample T,
              U extends @Sample Runnable,
              V extends @Sample String,
              W extends @Sample List<?>,
              X extends @Sample ArrayList<?>> {

          public static void main(String[] args) {
              System.out.println(Foo.class.getTypeParameters()[1].getAnnotatedBounds()[0].isAnnotationPresent(Sample.class));
              System.out.println(Foo.class.getTypeParameters()[2].getAnnotatedBounds()[0].isAnnotationPresent(Sample.class));
              System.out.println(Foo.class.getTypeParameters()[3].getAnnotatedBounds()[0].isAnnotationPresent(Sample.class));
              System.out.println(Foo.class.getTypeParameters()[4].getAnnotatedBounds()[0].isAnnotationPresent(Sample.class));
              System.out.println(Foo.class.getTypeParameters()[5].getAnnotatedBounds()[0].isAnnotationPresent(Sample.class));
          }
      }

      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.TYPE_USE)
      @interface Sample { }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None, it is however simple to see why this is happening. javac writes bounds that are "non-primary", i.e. not an interface type at index 1 instead of 0 even if there is no class type bound. The reflection API does not correctly account for this.

      The type references in the class file can be interpreted as follows using ASM:

              System.out.println(new TypeReference(285278208).getTypeParameterBoundIndex());
              System.out.println(new TypeReference(285344000).getTypeParameterBoundIndex());
              System.out.println(new TypeReference(285409280).getTypeParameterBoundIndex());
              System.out.println(new TypeReference(285475072).getTypeParameterBoundIndex());
              System.out.println(new TypeReference(285540352).getTypeParameterBoundIndex());

      printing

      0
      1
      0
      1
      0

      This does not make much sense in the first place and this is neither specified in this way in the JVMS.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              darcy Joe Darcy
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: