Strict checking of correctness of containing type by Core Reflection

Joel Borggrén-Franck joel.franck at oracle.com
Mon Mar 11 09:23:55 PDT 2013


Sounds good to me.

cheers
/Joel

On Mar 8, 2013, at 9:45 PM, Alex Buckley <alex.buckley at oracle.com> wrote:

> Hi Joel,
> 
> Per the thread with Mike, I'm happy to proceed with specifying that TC simply needs a T[]-typed value element. Since that's what the RI does today, you should be happy too, right? Please confirm.
> 
> Alex
> 
> On 3/7/2013 4:48 PM, Alex Buckley wrote:
>> Hi Joel,
>> 
>> Yes, the compile-time definition of "containing annotation type" TC has
>> constraints on TC's value element, non-value elements, retention,
>> applicability (@Target), documentation, and inheritance.
>> 
>> I agree with your sharp observation that, for an instance of TC at
>> run-time, it is possible for getAnnotationsByType(T.class) to ignore
>> TC's non-value elements, retention, and documentation. The first two are
>> inherently correct at run-time, while the third is insignificant.
>> 
>> I think TC's applicability is insignificant too. At run-time, it could
>> be inapplicable to the element on which reflection finds @TC(value=...),
>> but the fact that @TC is found means TC (and actually T also) must have
>> been applicable there at compile-time. I think it's fine for
>> getAnnotationsByType(T.class) to unpack the packed @T's which were
>> repeated legally in the source program.
>> 
>> Finally, inheritance. If T and TC are both @Inherited, and @T @T is
>> applied to a class X, then removing @Inherited from TC would presumably
>> cause getAnnotationsByType(T.class) to not see @TC on subclass Y and so
>> not expose @T @T. That's a potentially serious behavioral
>> incompatibility for clients reflecting over Y. Should we stop the client
>> with an AnnotationFormatError? Maybe not. It is rather appealing to
>> check only the presence of a T[]-typed value element.
>> 
>> Alex
>> 
>> On 3/7/2013 4:38 AM, Joel Borggrén-Franck wrote:
>>> Hi Experts,
>>> 
>>> The latest 8misc.pdf currently define 6 criteria for a type TC to be the
>>> a containing type for T, further T is repeatable if(f) T is annotated
>>> with a @Repeatable annotation indicating TC, the containing type for T.
>>> 
>>> The javadoc for AnnotatedElement says that the new methods
>>> get*AnnotationsByType(Class) detects if the argument is a repeatable
>>> annotation type and in that case does the look through to find repeated
>>> instances. My interpretation of the wording "*repeatable annotation
>>> type* (JLS 9.6)" from the method javadoc is that the @Repeatable
>>> meta-annotation indicating TC _and_ all 6 correctness criteria on TC
>>> should be checked and enforced at runtime. If one or more fails an
>>> AnnotationFormatError should be thrown.
>>> 
>>> This is however not strictly necessary in order to unpack the container.
>>> You can unpack checking only that:
>>> 
>>> * @Repeatable on T indicates a TC
>>> 
>>> * If you find an instance of TC then:
>>> 
>>> ** T and TC have suitable targets for the AnnotatedElement your are
>>> reflecting on (this is currently missing in the RI)
>>> 
>>> ** TC has an T-array valued value() element
>>> 
>>> 
>>> - You don't need to check @Documented.
>>> 
>>> - The VM should have enforced that all elements on TC either have a
>>> default or an explicit value, so you can get by without verifying that
>>> all non-value() elements have a default.
>>> 
>>> - Retention will by necessity be RUNTIME for both otherwise either the
>>> container or the repeated instances will be invisible.
>>> 
>>> - Inheritance works the same way.
>>> 
>>> I can see pros and cons with being lenient and not enforcing all 6
>>> correctness criteria, for example I'm not a big fan of the idea of
>>> throwing an error for a missing @documented. On the other hand there
>>> might be some surprises lurking in not bing strict on inheritance.
>>> 
>>> So how strict should we be? Comments much appreciated!
>>> 
>>> cheers
>>> /Joel




More information about the enhanced-metadata-spec-discuss mailing list