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

NullPointerException from AnnotationParser.parseArray via Class.isAnnotationPresent after bin-incompat change to ann signature

    Details

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_131"
      Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux … 4.10.0-22-generic #24-Ubuntu SMP Mon May 22 17:43:20 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      After making a binary-incompatible change to the definition of an annotation, some reflective calls dealing with annotations yield undeclared `NullPointerException`s. (`NullPointerException` is a documented possibility, but for an entirely different reason.) Known to occur for at least `Class.getAnnotation` and `Class.isAnnotationPresent`, but there may be other triggers.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the attached demo script.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      true
      single
      true
      <some kind of AnnotationTypeMismatchException>
      true
      [single]
      true
      <some kind of AnnotationTypeMismatchException>
      ACTUAL -
      true
      single
      true
      Exception in thread "main" java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract java.lang.String[] test.Ann.value() (Found data of type class java.lang.String[single])
      at sun.reflect.annotation.AnnotationTypeMismatchExceptionProxy.generateException(AnnotationTypeMismatchExceptionProxy.java:57)
      at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:84)
      at com.sun.proxy.$Proxy1.value(Unknown Source)
      at test.Demo.main(Demo.java:6)
      true
      [single]
      java.lang.NullPointerException
      at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
      at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
      at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
      at java.lang.Class.createAnnotationData(Class.java:3521)
      at java.lang.Class.annotationData(Class.java:3510)
      at java.lang.Class.getAnnotation(Class.java:3415)
      at java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:258)
      at java.lang.Class.isAnnotationPresent(Class.java:3425)
      at test.Demo.main(Demo.java:5)
      Exception in thread "main" java.lang.NullPointerException
      at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
      at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
      at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
      at java.lang.Class.createAnnotationData(Class.java:3521)
      at java.lang.Class.annotationData(Class.java:3510)
      at java.lang.Class.getAnnotation(Class.java:3415)
      at test.Demo.main(Demo.java:9)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Both unexpected errors come down to

      java.lang.NullPointerException
      at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
      at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
      at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
      at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
      at java.lang.Class.createAnnotationData(Class.java:3521)
      at java.lang.Class.annotationData(Class.java:3510)
      at …

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      #!/bin/sh
      rm -rf src bin
      mkdir -p src/test
      cat >src/test/Demo.java <<EOF
      package test;
      public class Demo {
          public static void main(String[] args) {
              System.out.println(Klazz.class.isAnnotationPresent(Ann.class));
              System.out.println(Klazz.class.getAnnotation(Ann.class).value());
          }
      }
      EOF
      cat >src/test/Ann.java <<EOF
      package test;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Ann {
          String value();
      }
      EOF
      cat >src/test/Klazz.java <<EOF
      package test;
      @Ann("single")
      public class Klazz {}
      EOF
      mkdir bin
      javac -d bin -classpath bin src/test/*.java
      java -cp bin test.Demo
      cat >src/test/Demo.java <<EOF
      package test;
      import java.util.Arrays;
      public class Demo {
          public static void main(String[] args) {
              System.out.println(Klazz.class.isAnnotationPresent(Ann.class));
              System.out.println(Arrays.toString(Klazz.class.getAnnotation(Ann.class).value()));
          }
      }
      EOF
      cat >src/test/Ann.java <<EOF
      package test;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Ann {
          String[] value();
      }
      EOF
      javac -d bin -classpath bin src/test/Demo.java src/test/Ann.java
      java -cp bin test.Demo
      javac -d bin -classpath bin src/test/Klazz.java
      java -cp bin test.Demo
      cat >src/test/Demo.java <<EOF
      package test;
      public class Demo {
          public static void main(String[] args) {
              try {
                  System.out.println(Klazz.class.isAnnotationPresent(Ann.class));
              } catch (Exception x) {
                  x.printStackTrace();
              }
              System.out.println(Klazz.class.getAnnotation(Ann.class).value());
          }
      }
      EOF
      cat >src/test/Ann.java <<EOF
      package test;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Ann {
          String value();
      }
      EOF
      javac -d bin -classpath bin src/test/Demo.java src/test/Ann.java
      java -cp bin test.Demo
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Catch undeclared unchecked exceptions when calling annotation-related reflective methods.

        Activity

        Hide
        psonal Pallavi Sonal added a comment -
        To reproduce the issue, run the attached script.
        Following are the results :
        JDK 8u131 - Fail
        JDK 9-ea+175 - Fail

        Following is the output:
        true
        single
        true
        Exception in thread "main" java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract java.lang.String[] test.Ann.value() (Found data of type class java.lang.String[single])
        at java.base/sun.reflect.annotation.AnnotationTypeMismatchExceptionProxy.generateException(AnnotationTypeMismatchExceptionProxy.java:57)
        at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:85)
        at com.sun.proxy.$Proxy1.value(Unknown Source)
        at test.Demo.main(Demo.java:6)
        true
        [single]
        java.lang.NullPointerException
        at java.base/sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
        at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
        at java.base/java.lang.Class.createAnnotationData(Class.java:3730)
        at java.base/java.lang.Class.annotationData(Class.java:3719)
        at java.base/java.lang.Class.getAnnotation(Class.java:3624)
        at java.base/java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:262)
        at java.base/java.lang.Class.isAnnotationPresent(Class.java:3634)
        at test.Demo.main(Demo.java:5)
        Exception in thread "main" java.lang.NullPointerException
        at java.base/sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532)
        at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
        at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
        at java.base/java.lang.Class.createAnnotationData(Class.java:3730)
        at java.base/java.lang.Class.annotationData(Class.java:3719)
        at java.base/java.lang.Class.getAnnotation(Class.java:3624)
        at test.Demo.main(Demo.java:9)
        Show
        psonal Pallavi Sonal added a comment - To reproduce the issue, run the attached script. Following are the results : JDK 8u131 - Fail JDK 9-ea+175 - Fail Following is the output: true single true Exception in thread "main" java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract java.lang.String[] test.Ann.value() (Found data of type class java.lang.String[single]) at java.base/sun.reflect.annotation.AnnotationTypeMismatchExceptionProxy.generateException(AnnotationTypeMismatchExceptionProxy.java:57) at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:85) at com.sun.proxy.$Proxy1.value(Unknown Source) at test.Demo.main(Demo.java:6) true [single] java.lang.NullPointerException at java.base/sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532) at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) at java.base/java.lang.Class.createAnnotationData(Class.java:3730) at java.base/java.lang.Class.annotationData(Class.java:3719) at java.base/java.lang.Class.getAnnotation(Class.java:3624) at java.base/java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:262) at java.base/java.lang.Class.isAnnotationPresent(Class.java:3634) at test.Demo.main(Demo.java:5) Exception in thread "main" java.lang.NullPointerException at java.base/sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:532) at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) at java.base/java.lang.Class.createAnnotationData(Class.java:3730) at java.base/java.lang.Class.annotationData(Class.java:3719) at java.base/java.lang.Class.getAnnotation(Class.java:3624) at test.Demo.main(Demo.java:9)

          People

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

            Dates

            • Created:
              Updated: