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

getAnnotatedOwnerType does not handle static nested classes correctly

    XMLWordPrintable

    Details

      Backports

        Description

        The implementation of getAnnotatedOwnerType does not handle static member classes correctly.

        A JVMS9 4.7.20.2 type_path_kind of 1 indicates that an annotation occurs deeper in a nested annotatable type.

        For example, assume:

        class Outer {
          class Inner {}
        }

        Given the type `Outer.Inner`, both the inner type (Inner) and its enclosing type (Outer) are annotatable. For `Outer . @Foo Inner`, a type path containing `[INNER_TYPE]` is needed to indicate that the annotation appears on Inner, not on Outer.

        However, assume a static nested class:

        class Outer {
          static class Nested {}
        }

        Given the type `Outer.Nested`, Nested is an annotatable type and Outer is a "scoping construct" rather than an annotatable type. So, for `Outer . @Foo Nested`, no type path is needed (path_length = 0) since Nested is the only annotable type.

        getAnnotatedOwnerType's handling of nested classes does not distinguish between inner classes (non-static) and static member classes, and incorrectly propagates annotations on static member classes to their enclosing type.

        Example:

        ```
        import static java.lang.annotation.ElementType.TYPE_USE;
        import static java.lang.annotation.RetentionPolicy.RUNTIME;

        import java.lang.annotation.Retention;
        import java.lang.annotation.Target;
        import java.lang.reflect.AnnotatedType;
        import java.util.Arrays;

        class T {
          @Retention(RUNTIME)
          @Target(TYPE_USE)
          @interface A {}

          class One {}

          static class Two {}

          T.@A One one;
          T.@A Two two;

          public static void main(String[] args) throws Exception {
            test("one");
            test("two");
          }

          static void test(String fieldName) throws Exception {
            AnnotatedType type = T.class.getDeclaredField(fieldName).getAnnotatedType();
            System.err.println("type annotations: " + Arrays.toString(type.getAnnotations()));
            System.err.println(
                "owner type annotations: "
                    + Arrays.toString(type.getAnnotatedOwnerType().getAnnotations()));
          }
        }
        ```

        Tested with java full version "10+44".

        $ javac T.java && java T
        type annotations: [@T$A()]
        owner type annotations: []
        type annotations: [@T$A()]
        owner type annotations: [@T$A()]

        Note that the type annotation on `T.@A Two` is incorrectly reported as being both on `Two` and its scoping construct `T`.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  cushon Liam Miller-Cushon
                  Reporter:
                  cushon Liam Miller-Cushon
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  5 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: