Hi Peter,

On my way to dinner I realized we have a problem for inherited annotations 
there are inherited over two (or more) declarations. I believe this is 
essentially the issue you highlighted though I will look into this tomorrow.

On 22 okt 2013, at 21:20, Peter Levart <peter.lev...@gmail.com> wrote:

> I think the problem could be solved in two ways:
> 
> - by explicitly scanning the inheritance chain for the 1st class that has the 
> annotations of type T present directly or indirectly (by containment).
> 

Yes, this is how I solved it for javax.lang.model and this is how I think we 
should fix this.

> - by "canonicalizing" the representation of the repeating annotations in the 
> class file attributes. By this I mean that each repeating annotation is 
> placed inside it's container at compile-time even if it is a single 
> annotation of a particular type. This would mean that some features like 
> specifying different @Targets or @Retentions for repeating annotation types 
> and their containers would be prohibited and the specification would have to 
> be changed. But I think this way the "inheritance" aspect of repeating 
> annotations would be consistent even if not "looking through" containers (by 
> using the old JDK7 API)...
> 
> The "canonicalization" could be performed at runtime though, and I think 
> there were such attempts already in the past. What happened to them?
> 

There hasn't been any attempt to do this at runtime. Fwiw I don't think this is 
worth the complexity unless someone proves the iterative lookup on super types 
is a performance issue.

cheers
/Joel

> 
> Regards, Peter
> 
> On 10/22/2013 02:57 PM, Peter Levart wrote:
>> Hi,
>> 
>> The spec says:
>> 
>> When the new get[Declared]AnnotationsByType(Class<T>) methods are 
>> called for a repeatable annotation type T, the question is how to extend the 
>> policy 
>> to handle multiple annotations of type T on the superclass and/or subclass. 
>> Oracle 
>> proposes the following policy for Java SE 8: 
>> 
>> • If a class declaration does not have either a "directly present" 
>> annotation of 
>> type T or an "indirectly present by containment" annotation of type T, the 
>> class 
>> declaration may be "associated" with an annotation of type T due to 
>> inheritance. 
>> 
>> • If a class declaration does have either a "directly present" annotation of 
>> type T 
>> or an "indirectly present by containment" annotation of type T, the 
>> annotation 
>> is deemed to "override" every annotation of type T which is "associated" 
>> with 
>> the superclass. 
>> 
>> This policy for Java SE 8 is reified in the following definitions: 
>> 
>> • An annotation A is directly present on an element E if E has a 
>> RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations or 
>> RuntimeVisibleTypeAnnotations attribute, and the attribute contains A.1.2 
>> Core Reflection API REPEATING ANNOTATIONS 
>> 12 
>> 
>> • An annotation A is indirectly present on an element E if E has a 
>> RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations or 
>> RuntimeVisibleTypeAnnotations attribute, and A's type is repeatable, and the 
>> attribute contains exactly one annotation whose value element contains A and 
>> whose type is the containing annotation type of A's type (§9.6). 
>> 
>> • An annotation A is present on an element E if either: 
>>  - A is directly present on E; or 
>>  - No annotation of A's type is directly present on E, and E is a class, and 
>> A's type 
>> is inheritable (§9.6.3.3), and A is present on the superclass of E. 
>> 
>> • An annotation A is associated with an element E if either: 
>>  - A is directly or indirectly present on E; or 
>>  - No annotation of A's type is directly or indirectly present on E, and E 
>> is a class, 
>> and A's type is inheritable (§9.6.3.3), and A is associated with the 
>> superclass 
>> of E. 
>> 
>> 
>> So I guess E.class.getAnnotations() returns the annotations "present" on the 
>> E
>> and E.class.getAnnotationsByType(A.class) returns the annotations of type A 
>> "associated" with E
>> 
>> Am I right?
>> 
>> Let's just focus on "associated" part now - the getAnnotationsByType method. 
>> The following test:
>> 
>> http://cr.openjdk.java.net/~plevart/jdk8-tl/RepearingAnnotations/InheritedRepeatingAnnotationsTest.java
>> 
>> dumps @Repeatable @Inherited annotations "associated" with the following 
>> classes:
>> 
>> @Ann(10)
>> class A1 {}
>> 
>> @Ann(20)
>> class A2 extends A1 {}
>> 
>> class A3 extends A2 {}
>> 
>> 
>> @Ann(10) @Ann(11)
>> class B1 {}
>> 
>> @Ann(20)
>> class B2 extends B1 {}
>> 
>> class B3 extends B2 {}
>> 
>> 
>> @Ann(10)
>> class C1 {}
>> 
>> @Ann(20) @Ann(21)
>> class C2 extends C1 {}
>> 
>> class C3 extends C2 {}
>> 
>> 
>> @Ann(10) @Ann(11)
>> class D1 {}
>> 
>> @Ann(20) @Ann(21)
>> class D2 extends D1 {}
>> 
>> class D3 extends D2 {}
>> 
>> 
>> Here's the output:
>> 
>> 
>> class A2: [@Ann(value=20)]
>> class B2: [@Ann(value=20)]
>> class C2: [@Ann(value=20), @Ann(value=21)]
>> class D2: [@Ann(value=20), @Ann(value=21)]
>> 
>> class A3: [@Ann(value=20)]
>> class B3: [@Ann(value=10), @Ann(value=11), @Ann(value=20)]
>> class C3: [@Ann(value=10), @Ann(value=20), @Ann(value=21)]
>> class D3: [@Ann(value=20), @Ann(value=21)]
>> 
>> 
>> 
>> Class B3 is showing @Ann(10) and @Ann(11), while class C3 is showing 
>> @Ann(10) as being "associated" with them, but they should not, right?
>> 
>> Class B3 should show the same annotations as B2 and class C3 should show the 
>> same annotations as class C2, I think.
>> 
>> 
>> Regards, Peter
>> 
>> 
>>  On 10/22/2013 01:03 PM, Joel Borggrén-Franck wrote:
>>> Hi Peter,
>>> 
>>> Spec is here: 
>>> http://cr.openjdk.java.net/~abuckley/8misc.pdf
>>> 
>>> 
>>> FYI I pushed this before I saw your mail but I do think the code is 
>>> correct. An extra pair of eyes would be great though!
>>> 
>>> FWIW I suspect we can be better with regards to allocation especially if we 
>>> optimize for the common case where there is either a single annotation or a 
>>> single container, but that will have to be a follow up.
>>> 
>>> Btw there are a lot of extra test cases in the langtools repository (!?!) 
>>> look in 
>>> langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java
>>> 
>>> cheers
>>> /Joel
>>> 
>>> On 22 okt 2013, at 18:50, Peter Levart 
>>> <peter.lev...@gmail.com>
>>>  wrote:
>>> 
>>> 
>>>> Hi, I would just like to ask for a pointer to some specification document 
>>>> that describes inheritance of repeating annotations. I couldn't find one 
>>>> on the net.
>>>> 
>>>> I have a feeling there's something wrong with the logic of 
>>>> AnnotationsSuport.getAssociatedAnnotations. Why? Because it is based on 
>>>> two maps: declaredAnnotations map and allAnnotations map. The later is a 
>>>> map of inherited and/or declared annotations which is aggregated without 
>>>> the knowledge of repeating annotations (the containers). I doubt this map 
>>>> keeps enough information to reconstruct a sound set of inherited and/or 
>>>> declared repeating annotations in all situations.
>>>> 
>>>> But I'd like to 1st see the specification before showing you some examples 
>>>> where problems arise.
>>>> 
>>>> Regards, Peter
>>>> 
>>>> On 10/22/2013 12:21 PM, Joel Borggrén-Franck wrote:
>>>> 
>>>>> Hi Andreas,
>>>>> 
>>>>> A few nits:
>>>>> 
>>>>> Class.java:
>>>>> 
>>>>>  import java.util.Collection;
>>>>> +import java.util.Collections;
>>>>>  import java.util.HashSet;
>>>>> 
>>>>> unused import.
>>>>> 
>>>>> AnnotationSupport.java:
>>>>> 
>>>>> +    /**
>>>>> +     * Equivalent to calling {@code 
>>>>> getDirectlyAndIndirectlyPresentAnnotations(
>>>>> +     * annotations, annoClass, false)}.
>>>>> +     */
>>>>> 
>>>>> I think it is equivalent to annotations, annoClass, true
>>>>> 
>>>>> Otherwise looks good. I can sponsor this fix.
>>>>> 
>>>>> cheers
>>>>> /Joel
>>>>> 
>>>>> On 21 okt 2013, at 21:01, Andreas Lundblad 
>>>>> <andreas.lundb...@oracle.com>
>>>>>  wrote:
>>>>> 
>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> New revision up for review:
>>>>>> 
>>>>>> 
>>>>>> http://aoeu.se/webrevs/8019420-and-8004912/webrev.01
>>>>>> 
>>>>>> 
>>>>>> The following has been addressed since webrev.00:
>>>>>> 
>>>>>> - Order of directly / indirectly present annotations now respects the 
>>>>>> order of the keys in the given map of annotations.
>>>>>> 
>>>>>> - A new test has been added to test the above behavior.
>>>>>> 
>>>>>> best regards,
>>>>>> Andreas
>>>>>> 
>>>>>> 
>>>>>> ----- Original Message -----
>>>>>> From: 
>>>>>> andreas.lundb...@oracle.com
>>>>>> 
>>>>>> To: 
>>>>>> core-libs-dev@openjdk.java.net
>>>>>> 
>>>>>> Sent: Wednesday, October 16, 2013 4:00:08 PM GMT +01:00 Amsterdam / 
>>>>>> Berlin / Bern / Rome / Stockholm / Vienna
>>>>>> Subject: RFR: 8004912: Repeating annotations - getAnnotationsByType is 
>>>>>> not working as expected
>>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> Please review the fix for JDK-8004912 and JDK-8019420 below.
>>>>>> 
>>>>>> Description:
>>>>>> 
>>>>>> The behavior of Class.get[Declared]AnnotationsByType was wrong. These 
>>>>>> methods delegate to sun.reflect.annotation.AnnotationSupport which has 
>>>>>> been rewritten.
>>>>>> 
>>>>>> NonInheritableContainee.java is added and contains the test referred to 
>>>>>> in JDK-8019420.
>>>>>> 
>>>>>> RepeatedUnitTest.java have been updated to include the test cases in 
>>>>>> JDK-8004912.
>>>>>> 
>>>>>> There are more tests available in 
>>>>>> tl/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/ReflectionTest.java
>>>>>>  (NB. this file is in the langtools repo)
>>>>>> 
>>>>>> 
>>>>>> Link to web review:
>>>>>> 
>>>>>> http://cr.openjdk.java.net/~alundblad/8019420-and-8004912/
>>>>>> 
>>>>>> 
>>>>>> Link to bug reports:
>>>>>> 
>>>>>> https://bugs.openjdk.java.net/browse/JDK-8004912
>>>>>> https://bugs.openjdk.java.net/browse/JDK-8019420
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> -- Andreas Lundblad
>>>>>> 
>> 
> 

Reply via email to