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

Annotation property which is compiled as an array property but changed to a single element throws NullPointerException

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 17, 17-pool, 18
    • core-libs
    • None
    • behavioral
    • minimal
    • Low as the current implementation already throws a `NullPointerException` upon parsing the annotation such that code that is reading the annotation property cannot be reached in existing JVMs.

      Summary

      If an annotation member is changed to represent a single value rather than an array of elements, annotation values that were compiled prior to this change will cause a NullPointerException upon parsing the raw annotation data. Rather an AnnotationTypeMismatchException should be thrown upon accessing the data.

      Problem

      When an annotation member is defined as an array type but is later reduced to only allow a single element, OpenJDK's annotation parser relies on the raw annotation data that still represents an array while also reading the loaded annotation member type's component type, even if that is no longer an array type. As this component type is null for non-array types, the further processing in the annotation parser results in a NullPointerException.

      Solution

      Add an explicit check to see if the loaded annotation type of the annotation member still represents an array if the raw annotation data contains an array value for this annotation member. If this is not the case, an annotation proxy for AnnotationTypeMismatchException is created. For example, given an annotation and carrier

      @interface AnAnnotation {
        String[] value();
      }
      
      @AnAnnotation({"a", "b"})
      class Carrier {}

      if the annotation member's type is changed to a non-array type

      @interface AnAnnotation {
        String value();
      }

      an AnnotationTypeMismatchException is thrown upon reading AnAnnotation.value.

      Specification

      The change is already implied by the current Javadoc of AnnotationTypeMismatchException:

       * Returns the type of data found in the incorrectly typed element.
       * The returned string may, but is not required to, contain the value
       * as well.  The exact format of the string is unspecified and the string
       * may be {@code null}.

      That this exception can be thrown if an incompatible class change occurred is already documented in the Javadoc of AnnotatedElement:

       * Finally, attempting to read a member whose definition has evolved
       * incompatibly will result in a {@link
       * java.lang.annotation.AnnotationTypeMismatchException} or an
       * {@link java.lang.annotation.IncompleteAnnotationException}.

            winterhalter Rafael Winterhalter
            winterhalter Rafael Winterhalter
            Joel Borggrén-Franck (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: