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

Arrays of types that cannot be an annotation member do not yield exceptions

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 17
    • core-libs
    • None
    • behavioral
    • minimal
    • Hide
      In the current state, annotation processing code would likely already yield a runtime exception via a `NullPointerException` as annotation values cannot legally be `null`. With this change, this runtime exception would be replaced with a more descriptive `AnnotationTypeMismatchException` that indicates the problem when the property is read. Furthermore, an incompatible class change at runtime is rather rare and often results in generally dysfunctional programs.
      Show
      In the current state, annotation processing code would likely already yield a runtime exception via a `NullPointerException` as annotation values cannot legally be `null`. With this change, this runtime exception would be replaced with a more descriptive `AnnotationTypeMismatchException` that indicates the problem when the property is read. Furthermore, an incompatible class change at runtime is rather rare and often results in generally dysfunctional programs.

      Summary

      An annotation member that is defined as an array of a type where the component type is changed such that it can no longer be legally used for an annotation member is not discovered as such. As result, the OpenJDK's annotation parser assumes the type to be of an annotation type and returns an array of only null values, where an AnnotationTypeMismatchException should be thrown instead.

      Problem

      The annotation's member value is represented as a value of null values where null is not a legal value for an annotation member.

      Solution

      Upon discovering such an incompatible class change, the parser should generate an exception proxy for an AnnotationTypeMismatchException as it is also created for other incompatible changes. For example, for an annotation and carrier of the same annotation:

      @interface AnAnnotation {
        FormerEnum[] value();
      }
      
      @AnAnnotation({FormerEnum.VALUE})
      class Carrier {}

      if enum FormerEnum { VALUE } is changed to class FormerEnum { }, then the result of reading Carrier.class.getAnnotation(AnAnnotation.class).value() is changed from returning a value:

      [null]

      to throwing an AnnotationTypeMismatchException with string representation:

      /* Warning type mismatch! "FormerEnum.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:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: