Spec updates for repeating annotations (reflection)

Alex Buckley alex.buckley at oracle.com
Fri Dec 7 14:09:56 PST 2012


Paul, this is a good option to consider for get[Declared]Annotations(). 
I am generally in favor of giving power to the authors of annotation 
type, for then it is clear who annotation readers should blame when 
reflection results change.

Joe, Mike, any comment?

Alex

On 12/7/2012 2:06 PM, Paul Benedict wrote:
> Alex,
>
> What do you think about adding a new attribute on @ContainedFor (or
> vice-versa if I am wrong) that would specify if the container
> application should be returned by reflection? I am not fond of the
> current rules that try to make things "see through" based on esoteric
> conditions. I'd rather have it programatically controlled by the
> developer.
>
> Paul
>
> On Fri, Dec 7, 2012 at 3:59 PM, Alex Buckley <alex.buckley at oracle.com> wrote:
>> I have added further examples in section 1.2 (core reflection) to cover what
>> I believe to be all critical combinations of base annotations and container
>> annotations under inheritance.
>>
>> Example 1.2-5 is interesting because it raises the question of whether
>> getAnnotations() should expose an inherited container annotation when its
>> containerized base annotations are overridden. Let's break it down:
>>
>> - With no container annotation inheritance, things are simple:
>>
>>    1.2-3:
>>      @Foo(0) @FooContainer({@Foo(1), at Foo(2)}) class A {}
>>
>>      A.class.getAnnotations() = [ @Foo(0), @Foo(1), @Foo(2) ]
>>
>>    1.2-4:
>>      @Foo(0)                          class A {}
>>      @FooContainer({@Foo(1), at Foo(2)}) class B extends A {}
>>
>>      B.class.getAnnotations() = [ @Foo(1), @Foo(2) ]
>>
>> - With container annotation inheritance + overriding, things are not simple:
>>
>>    1.2-5:
>>      @FooContainer({@Foo(1), at Foo(2)}) class A {}
>>      @Foo(0)                          class B extends A {}
>>
>>      B.class.getAnnotations() = [ @Foo(0) /* and @FooContainer(..)? */ ]
>>
>> I tend to think that container annotations should be invisible unless
>> requested explicitly via get[Declared]Annotation[s](FooContainer.class).
>> Consequently, in 1.2-5, I do not show @FooContainer(..) being returned by
>> getAnnotations() after Foo has become repeatable with FooContainer. Comments
>> welcome.
>>
>> Alex
>>
>> On 12/6/2012 12:01 PM, Alex Buckley wrote:
>>>
>>> I have updated section 1.3 of the spec as proposed below.
>>>
>>> I have also 1) added remarks at the start of chapter 1 to explain the
>>> design, and 2) added examples in section 1.2 (core reflection) to cover
>>> more scenarios.
>>>
>>> The spec is at http://cr.openjdk.java.net/~abuckley/8misc.pdf as usual.
>>>
>>> Alex
>>>
>>> On 12/5/2012 2:46 PM, Alex Buckley wrote:
>>>>
>>>> We discovered two small issues with section 1.3 of the spec:
>>>>
>>>>
>>>> 1. The spec proposes a new method, Element.getAnnotations().
>>>>
>>>> This method is proposed for consistency with
>>>> AnnotatedElement.getAnnotations(), but it turns out to be difficult to
>>>> implement in the context of the language model. The problem is that, at
>>>> compile-time, there might not be instances of Class objects for the
>>>> annotations we try to look at. The other new methods -
>>>> Element.getAnnotation[s](Class<T>) - do not have this issue since their
>>>> callers must supply a Class object.
>>>>
>>>> It would be possible for Element.getAnnotations() to throw exceptions if
>>>> necessary Class objects were not found, but there is no good unchecked
>>>> exception type available in the language model API. It would also be
>>>> possible to skip over annotations for which Class objects are
>>>> unavailable, and return incomplete results, but this seems undesirable.
>>>>
>>>> I propose to drop the method. Essentially, it's fine in core reflection
>>>> but too brittle for the language model.
>>>>
>>>>
>>>> 2. The spec proposes to refine Element.getAnnotationMirrors() and
>>>> Elements.getAllAnnotationMirrors().
>>>>
>>>> If the language model API only has a class file available for the
>>>> element on which annotation mirrors are requested, then the API cannot
>>>> be sure that it's right to "look through" @FooContainer (if directly
>>>> present on the element) and return @Foo mirrors.
>>>>
>>>> This is true even if FooContainer is a well-formed containing annotation
>>>> type available to the API. The source code of the element - which the
>>>> API strives to reflect - could literally have said @FooContainer(...).
>>>> Unfortunately, a compiler has no way to mark a container annotation as
>>>> "synthesized" during class file generation.
>>>>
>>>> It would be possible to adopt a policy of always looking through
>>>> container annotations on an element. This requires the language model
>>>> API to recognize container annotations, which in turn requires loading
>>>> the annotation's class file, which might not always be available.
>>>>
>>>> I propose to adopt this policy, while allowing the methods to sometimes
>>>> expose container annotations even if not present in source code.
>>>>
>>>>
>>>> Alex



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