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

Annotations on type arguments of a super class which is a nested class are broken

XMLWordPrintable

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

      ADDITIONAL OS VERSION INFORMATION :
      Linux eli-desktop 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      This bug appears to be related to JDK-8146167

      Type annotations with placed on the type arguments of a super type do not work in certain cases. As a simple example of such an annotation to aid in description:

          class Container {
              static class Nested<T> {}
              
              static class NestedExtendsNested extends Nested<@TestAnnotation Object> {} // <- dropped annotation
          }

      In the case of anonymous classes, the presence of the annotation may even cause a compiler error:
         
          class Container {
      class Inner<T> {}
              
              {
                  new Container().new Inner<Object>() {} // okay
                  new Container().new Inner<@TestAnnotation Object>() {} // error!
              }
          }

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Try to reflect over `NestedExtendsNested` in the example above and you will see that the annotation is not present even if it is specified to have runtime retention.

      Try to compile the second example and javac will crash.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The code should compile and the annotation should be present in every case.
      ACTUAL -
      The code may not compile or the annotation may not be present.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      An exception has occurred in the compiler (1.8.0_101). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
      java.lang.AssertionError: Could not determine position of tree Inner<@TestAnnotation() Object> within frame new Inner<@TestAnnotation() Object>(<*nullchk*>new Container()){
          
          (.Container x0) {
              x0.super();
          }
      }


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import static org.junit.Assert.assertNotNull;

      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 org.junit.Test;
      import org.junit.runner.RunWith;
      import org.junit.runners.Parameterized;
      import org.junit.runners.Parameterized.Parameters;

      @Retention(value = RetentionPolicy.RUNTIME)
      @Target(value = ElementType.TYPE_USE)
      @interface TestAnnotation {}

      class OuterExtendsNested extends Container.Nested<@TestAnnotation Object> {}

      class Container {
      public class Inner<T> {}

      public class InnerExtendsNested extends Nested<@TestAnnotation Object> {}

      public static class Nested<T> {}

      public static class NestedExtendsNested extends Nested<@TestAnnotation Object> {}
      }

      /**
       * Test for bug JDK-8146167 in javac.
       *
       * @author Elias N Vasylenko
       */
      @SuppressWarnings("javadoc")
      @RunWith(Parameterized.class)
      public class JavacSupertypeAnnotationsTest {

      @Parameters(name = "{0}")
      public static Object[][] testClasses() {
      class StaticInner<T> {}

      class StaticInnerExtendsStaticInner extends StaticInner<@TestAnnotation Object> {}

      return new Object[][] {

      // ecj and javac fail
      { "outer extends nested", OuterExtendsNested.class },

      // ecj and javac fail
      { "inner extends nested", Container.InnerExtendsNested.class },

      // ecj and javac fail
      { "nested extends nested", Container.NestedExtendsNested.class },

      // ecj and javac fail
      { "anonymous extends nested", new Container.Nested<@TestAnnotation Object>() {}.getClass() },

      // ecj fails
      { "static inner extends static inner", StaticInnerExtendsStaticInner.class },

      // ecj fails
      { "anonymous extends static inner", new StaticInner<@TestAnnotation Object>() {}.getClass() },

      // !javac compiler errors!
      { "anonymous extends inner", new Container().new Inner<@TestAnnotation Object>() {}.getClass() }

      };
      }

      private final Class<?> testClass;

      public JavacSupertypeAnnotationsTest(String testName, Class<?> testClass) {
      this.testClass = testClass;
      }

      @Test
      public void supertypeParameterAnnotationPresenceTest() {
      AnnotatedParameterizedType superType = (AnnotatedParameterizedType) testClass.getAnnotatedSuperclass();

      AnnotatedType superTypeParameter = superType.getAnnotatedActualTypeArguments()[0];

      assertNotNull(superTypeParameter.getAnnotation(TestAnnotation.class));
      }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      None known!

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

              Created:
              Updated: