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

No compiler error on duplicate annotation leads to a run-time exception

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 8u40
    • tools
    • x86
    • os_x

      FULL PRODUCT VERSION :
      java version "1.8.0_40"
      Java(TM) SE Runtime Environment (build 1.8.0_40-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64

      A DESCRIPTION OF THE PROBLEM :
      This code is compilable by javac, but should not be:

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE_USE, ElementType.FIELD})
      @interface Bar {}

      public class Test {
          @Bar java.lang.@Bar String foo = null; // Must be an error: Bar is not a repeatable annotation type

          public static void main(String[] args) throws Throwable {
              // This fails at runtime, because the declaration above is wrong
              Test.class.getDeclaredField("foo").getAnnotatedType();
          }
      }

      When I run this code, I get a runtime exception:

      Exception in thread "main" java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface Bar: @Bar()
      at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:360)
      at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:139)
      at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:65)
      at sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedType(TypeAnnotationParser.java:79)
      at java.lang.reflect.Field.getAnnotatedType(Field.java:1170)
      at Test.main(Test.java:22)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run this code:

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE_USE, ElementType.FIELD})
      @interface Bar {}

      public class Test {
          @Bar java.lang.@Bar String foo = null; // Must be an error: Bar is not a repeatable annotation type

          public static void main(String[] args) throws Throwable {
              // This fails at runtime, because the declaration above is wrong
              Test.class.getDeclaredField("foo").getAnnotatedType();
          }
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Compilation error: (19, 25) java: Bar is not a repeatable annotation type
      ACTUAL -
      Compiles fine, AnnotationFormatError exception at runtime

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface Bar: @Bar()
      at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:360)
      at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(AnnotatedTypeFactory.java:139)
      at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:65)
      at sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedType(TypeAnnotationParser.java:79)
      at java.lang.reflect.Field.getAnnotatedType(Field.java:1170)
      at Test.main(Test.java:22)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE_USE, ElementType.FIELD})
      @interface Bar {}

      public class Test {
          @Bar java.lang.@Bar String foo = null; // Must be an error: Bar is not a repeatable annotation type

          public static void main(String[] args) throws Throwable {
              // This fails at runtime, because the declaration above is wrong
              Test.class.getDeclaredField("foo").getAnnotatedType();
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Remove the duplicate annotation or mark the annotation declaration as @Repeatable

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

              Created:
              Updated: