From eric.mccorkle at oracle.com Fri Mar 1 12:25:47 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Fri, 01 Mar 2013 15:25:47 -0500 Subject: Parameter::getName() In-Reply-To: <512FA8AC.6030800@oracle.com> References: <512F9901.8050807@oracle.com> <512FA8AC.6030800@oracle.com> Message-ID: <51310ECB.5050500@oracle.com> I will put out a patch in the near future addressing this. On 02/28/13 13:57, Alex Buckley wrote: > Eric, > > JDK-8007405 is marked as fixed in b78, but the corresponding changeset > (f21a4b761424) still has Parameter#getName saying parameter names "must > all the be distinct" (and some other spelling errors). > > Alex > > On 2/28/2013 9:50 AM, Eric McCorkle wrote: >> The parameter reflection API reports exactly what is present in a class >> file. It is correct that there is no guarantee parameter names are >> unique for a given method (consider, for example, a class file generated >> for a non-java language that allows the same name for multiple >> parameters) >> >> On 02/28/13 12:41, Paul Benedict wrote: >>> The opening Javadoc sentences: "Returns the name of the parameter. The >>> names of the parameters of a single executable must all the be >>> distinct." >>> >>> It was my understanding that parameter names are not necessarily >>> distinct: >>> http://mail.openjdk.java.net/pipermail/enhanced-metadata-spec-discuss/2013-February/000148.html >>> >>> >>> Paul >>> From michael.keith at oracle.com Fri Mar 1 12:56:58 2013 From: michael.keith at oracle.com (michael keith) Date: Fri, 01 Mar 2013 15:56:58 -0500 Subject: some more fiddling In-Reply-To: <51268233.9060408@oracle.com> References: <5101A4A2.7030801@oracle.com> <5101B255.4060904@oracle.com> <51268233.9060408@oracle.com> Message-ID: <5131161A.3080003@oracle.com> Thanks for the update, Joe. I changed the repeating annotations to use @Repeatable, recompiled with jdk 7 and re-ran the tests using the b77 JRE. The tests ran fine so we are still on track. I have started to try out the new look-through methods and have found no issues so far. (I have not been able to test the new compiler checks since my IDE limits me to using JDK 7 to compile.) Thanks, -Mike On 21/02/2013 3:23 PM, Joe Darcy wrote: > Hello Mike, > > Following up on this thread... > > On 1/24/2013 2:14 PM, Joe Darcy wrote: >> Hi Mike, >> >> On 1/24/2013 1:16 PM, michael keith wrote: >>> So I did some playing around with b72 in a couple of ways. >>> >>> First, I went and modified all of the current JPA container >>> annotations to be JDK 8 repeatable (using @ContainerFor and >>> @ContainedBy, since @Repeatable did not seem to be included) and >>> compiled it using b72. >> >> The transition to the simplified @Repeatable model is happening in >> stages. Build 73 of JDK 8 has the Repeatable type, but no compiler >> and reflection support. The compiler support is in the team >> repository now (bug 8006119) and should appear in a near-future >> promoted build. However, the core reflection changes to revert back >> to the JDK 7 and earlier behavior are not implemented yet. >> >>> Then I took the JPA RI (EclipseLink) code and its existing JPA tests >>> and built them using JDK 1.7_11. I then ran the tests using b72 and >>> found that all of the tests passed, so basically existing code and >>> test cases compiled using a previous JDK will continue to work (at >>> least in the test cases that I ran). So the first "do no harm" test >>> seems to have passed :-) >> >> Good to hear :-) >> >>> >>> The next thing I did was up the ante and move on to creating tests >>> using new features (e.g. repeating annotations) to see how >>> compatible the code would be. In other words, I wanted to make sure >>> the same processing code could handle repeating annotations using >>> the old API. It turned out not to work, though, so either the >>> compatibility layer that we discussed before Christmas isn't done >>> yet, or the current support just doesn't work as expected. For >>> example, invoking getAnnotation(Foo.class) on both >>> >>> @Foo(1) @Foo(2) >>> class A {} >>> >>> and >>> >>> @FooContainer({@Foo(1), @Foo(2)}) >>> class A {} >>> >>> both returned @Foo(1). In both of these cases it should have >>> returned null. >>> >>> This, combined with the fact that the Repeatable annotation was not >>> shipped in b72 leads me to believe that the compatibility support is >>> still forthcoming. Do you folks have any estimates for when it will >>> be ready to try out? >>> >> >> The core reflection changes should be in a promoted build within a >> few weeks. >> >> > > The core reflection changes in question to revert the behavior of the > existing AnnotatedElement methods to be oblivious to repeatability are > in the current build of JDK 8, b77. > > Please re-run your experiments to see if the existing processing code > works running under JDK 8 with annotation types that have been > upgraded to be @Repeatable. (There is an in-progress rename of some of > the new methods, but that won't affect this experiment.) > > Thanks, > > -Joe > From alex.buckley at oracle.com Wed Mar 6 17:22:56 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 06 Mar 2013 17:22:56 -0800 Subject: Question for Mike re: changing containers Message-ID: <5137EBF0.1030509@oracle.com> Mike, we're pondering whether the new methods in core reflection should be strict about the relationship of containing type to repeatable type. Have you ever written @FooContainer({@Foo(1),...}) on a declartion, and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on clients using getAnnotation(Class) and getAnnotations() would be significant. Effectively we are wondering if a client using getAnnotationsByType(Foo.class) should be affected by such a change. Alex From michael.keith at oracle.com Wed Mar 6 23:10:37 2013 From: michael.keith at oracle.com (michael keith) Date: Thu, 07 Mar 2013 02:10:37 -0500 Subject: Question for Mike re: changing containers In-Reply-To: <5137EBF0.1030509@oracle.com> References: <5137EBF0.1030509@oracle.com> Message-ID: <51383D6D.4070309@oracle.com> Our usage of the container annotation has fairly consistently been a trivial mapping from the singular contained annotation to its pluralized containing form. We have, during development, changed the name of the singular annotation and then had to go and rename the container annotation to the plural form of the newly named singular one, but it would not be common at all to decide to rename the container one independent of the singular one, and I am talking about development, before clients exist. Existing clients of the current getAnnotation(Class) and getAnnotations() methods are written to reference both the repeatable and the container annotations directly, so renaming either one of them would be a breaking change that we would not generally undertake after the annotations have been created/released. I would not have expected a precompiled client of getAnnotationsByType(Foo.class) to be affected by such a change, though. The container annotation is meant to be transparent to them, isn't it? -Mike On 06/03/2013 8:22 PM, Alex Buckley wrote: > Mike, we're pondering whether the new methods in core reflection > should be strict about the relationship of containing type to > repeatable type. > > Have you ever written @FooContainer({@Foo(1),...}) on a declartion, > and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on > clients using getAnnotation(Class) and getAnnotations() would be > significant. > > Effectively we are wondering if a client using > getAnnotationsByType(Foo.class) should be affected by such a change. > > Alex From joel.franck at oracle.com Thu Mar 7 04:38:05 2013 From: joel.franck at oracle.com (=?ISO-8859-1?Q?Joel_Borggr=E9n-Franck?=) Date: Thu, 07 Mar 2013 13:38:05 +0100 Subject: Strict checking of correctness of containing type by Core Reflection Message-ID: <51388A2D.7090005@oracle.com> 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 From alex.buckley at oracle.com Thu Mar 7 16:48:01 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 07 Mar 2013 16:48:01 -0800 Subject: Strict checking of correctness of containing type by Core Reflection In-Reply-To: <51388A2D.7090005@oracle.com> References: <51388A2D.7090005@oracle.com> Message-ID: <51393541.7090407@oracle.com> 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 From alex.buckley at oracle.com Thu Mar 7 17:05:45 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 07 Mar 2013 17:05:45 -0800 Subject: Question for Mike re: changing containers In-Reply-To: <51383D6D.4070309@oracle.com> References: <5137EBF0.1030509@oracle.com> <51383D6D.4070309@oracle.com> Message-ID: <51393969.4070206@oracle.com> If you change: @Repeatable(FooContainer.class) @interface Foo {...} to: @Repeatable(OtherContainer.class) @interface Foo {...} then getAnnotationsByType(Foo.class) will seek out @OtherContainer. Any @FooContainer (generated by a compiler to wrap @Foo @Foo prior to the change) will be ignored. So, switching Foo's containing annotation type is behaviorally incompatible for reflective clients. There is no way around that, but actually, it wasn't what I meant to ask you! Suppose FooContainer is intended to be the containing annotation type for Foo forever. Do you ever tweak FooContainer's declaration, for example, expanding its applicability (adding entries to @Target) ? I ask because Joel and I are wondering how strict to be in getAnnotationsByType(Class) if FooContainer diverges slightly from Foo's expectations. No doubt FooContainer will be a proper "containing annotation type" for Foo almost all the time, since you can't compile @Foo @Foo otherwise - but maybe someone makes a mistake, where @Inherited is removed from FooContainer but not Foo, and then @Foo @Foo isn't inherited because @FooContainer isn't inherited - this would cause a subtle change in client behavior. I think we're heading towards saying this is just "OK", rather than raising an AnnotationFormatError. tl;dr There are many rules tying FooContainer to Foo, and maybe they just don't matter much at run-time. Alex On 3/6/2013 11:10 PM, michael keith wrote: > Our usage of the container annotation has fairly consistently been a > trivial mapping from the singular contained annotation to its pluralized > containing form. We have, during development, changed the name of the > singular annotation and then had to go and rename the container > annotation to the plural form of the newly named singular one, but it > would not be common at all to decide to rename the container one > independent of the singular one, and I am talking about development, > before clients exist. > > Existing clients of the current getAnnotation(Class) and > getAnnotations() methods are written to reference both the repeatable > and the container annotations directly, so renaming either one of them > would be a breaking change that we would not generally undertake after > the annotations have been created/released. > > I would not have expected a precompiled client of > getAnnotationsByType(Foo.class) to be affected by such a change, though. > The container annotation is meant to be transparent to them, isn't it? > > -Mike > > On 06/03/2013 8:22 PM, Alex Buckley wrote: >> Mike, we're pondering whether the new methods in core reflection >> should be strict about the relationship of containing type to >> repeatable type. >> >> Have you ever written @FooContainer({@Foo(1),...}) on a declartion, >> and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on >> clients using getAnnotation(Class) and getAnnotations() would be >> significant. >> >> Effectively we are wondering if a client using >> getAnnotationsByType(Foo.class) should be affected by such a change. >> >> Alex > From pbenedict at apache.org Thu Mar 7 20:13:11 2013 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 7 Mar 2013 22:13:11 -0600 Subject: Question for Mike re: changing containers In-Reply-To: <51393969.4070206@oracle.com> References: <5137EBF0.1030509@oracle.com> <51383D6D.4070309@oracle.com> <51393969.4070206@oracle.com> Message-ID: My armchair opinion here... I would let the container annotation dictate what is inherited or not. That's the "king" and what's contained is the "subject", so to speak. Repeating annotations are just syntatic sugar -- they always get contained regardless. Therefore, in terms of runtime, I propose that @Inherited on @Foo is completely ignored. It should all be driven on the container. Paul On Thu, Mar 7, 2013 at 7:05 PM, Alex Buckley wrote: > If you change: > > @Repeatable(FooContainer.**class) > @interface Foo {...} > > to: > > @Repeatable(OtherContainer.**class) > @interface Foo {...} > > then getAnnotationsByType(Foo.**class) will seek out @OtherContainer. Any > @FooContainer (generated by a compiler to wrap @Foo @Foo prior to the > change) will be ignored. So, switching Foo's containing annotation type is > behaviorally incompatible for reflective clients. > > There is no way around that, but actually, it wasn't what I meant to ask > you! > > Suppose FooContainer is intended to be the containing annotation type for > Foo forever. Do you ever tweak FooContainer's declaration, for example, > expanding its applicability (adding entries to @Target) ? > > I ask because Joel and I are wondering how strict to be in > getAnnotationsByType(Class) if FooContainer diverges slightly from Foo's > expectations. No doubt FooContainer will be a proper "containing annotation > type" for Foo almost all the time, since you can't compile @Foo @Foo > otherwise - but maybe someone makes a mistake, where @Inherited is removed > from FooContainer but not Foo, and then @Foo @Foo isn't inherited because > @FooContainer isn't inherited - this would cause a subtle change in client > behavior. I think we're heading towards saying this is just "OK", rather > than raising an AnnotationFormatError. > > tl;dr There are many rules tying FooContainer to Foo, and maybe they just > don't matter much at run-time. > > Alex > > On 3/6/2013 11:10 PM, michael keith wrote: > >> Our usage of the container annotation has fairly consistently been a >> trivial mapping from the singular contained annotation to its pluralized >> containing form. We have, during development, changed the name of the >> singular annotation and then had to go and rename the container >> annotation to the plural form of the newly named singular one, but it >> would not be common at all to decide to rename the container one >> independent of the singular one, and I am talking about development, >> before clients exist. >> >> Existing clients of the current getAnnotation(Class) and >> getAnnotations() methods are written to reference both the repeatable >> and the container annotations directly, so renaming either one of them >> would be a breaking change that we would not generally undertake after >> the annotations have been created/released. >> >> I would not have expected a precompiled client of >> getAnnotationsByType(Foo.**class) to be affected by such a change, >> though. >> The container annotation is meant to be transparent to them, isn't it? >> >> -Mike >> >> On 06/03/2013 8:22 PM, Alex Buckley wrote: >> >>> Mike, we're pondering whether the new methods in core reflection >>> should be strict about the relationship of containing type to >>> repeatable type. >>> >>> Have you ever written @FooContainer({@Foo(1),...}) on a declartion, >>> and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on >>> clients using getAnnotation(Class) and getAnnotations() would be >>> significant. >>> >>> Effectively we are wondering if a client using >>> getAnnotationsByType(Foo.**class) should be affected by such a change. >>> >>> Alex >>> >> >> From michael.keith at oracle.com Thu Mar 7 23:47:38 2013 From: michael.keith at oracle.com (michael keith) Date: Fri, 08 Mar 2013 02:47:38 -0500 Subject: Question for Mike re: changing containers In-Reply-To: <51393969.4070206@oracle.com> References: <5137EBF0.1030509@oracle.com> <51383D6D.4070309@oracle.com> <51393969.4070206@oracle.com> Message-ID: <5139979A.6030205@oracle.com> On 07/03/2013 8:05 PM, Alex Buckley wrote: > If you change: > > @Repeatable(FooContainer.class) > @interface Foo {...} > > to: > > @Repeatable(OtherContainer.class) > @interface Foo {...} > > then getAnnotationsByType(Foo.class) will seek out @OtherContainer. > Any @FooContainer (generated by a compiler to wrap @Foo @Foo prior to > the change) will be ignored. So, switching Foo's containing annotation > type is behaviorally incompatible for reflective clients. My point was only that the processing client code does not and should not change regardless of the container type when using the look-through methods. Clearly, processing a precompiled annotated class is not going to find the contained annotation if the container annotation has been changed in the interim. However, I think one would have to accept that after changing the container annotation one would have to recompile the annotated classes with the updated annotations. > > There is no way around that, but actually, it wasn't what I meant to > ask you! > > Suppose FooContainer is intended to be the containing annotation type > for Foo forever. Do you ever tweak FooContainer's declaration, for > example, expanding its applicability (adding entries to @Target) ? The elements of the annotation do not ever change for us from one release to another (we only ever have a single value() element that consists of an array of the contained annotation type) but modifying the meta-annotations of the containing annotation is something that can happen occasionally as they may get expanded on the contained annotation. Adding an entry to @Target is a good example, where an annotation is being extended to be allowed to be present on additional code elements. > > I ask because Joel and I are wondering how strict to be in > getAnnotationsByType(Class) if FooContainer diverges slightly from > Foo's expectations. No doubt FooContainer will be a proper "containing > annotation type" for Foo almost all the time, since you can't compile > @Foo @Foo otherwise - but maybe someone makes a mistake, where > @Inherited is removed from FooContainer but not Foo, and then @Foo > @Foo isn't inherited because @FooContainer isn't inherited - this > would cause a subtle change in client behavior. I think we're heading > towards saying this is just "OK", rather than raising an > AnnotationFormatError. As I think I mentioned in the past, I think the real annotation development happens on Foo, and the container annotation must get changed to match. In other words it is far more likely that I would change @Inherited on @Foo but forget to do so on @FooContainer. Anyway, that isn't really your question either ;-) My experience is that the meta-annotations on the container annotation should match exactly what is on the contained annotation (with the possible exception that I might only want @Documented to be on @Foo and not on @FooContainer, if that worked :-). In all other cases I would expect to be told at compile-time since it is likely an oversight if they don't match. I don't know that it is that important to catch at runtime, though, and I would likely opt out of the extra checking if it cost me some performance. > tl;dr There are many rules tying FooContainer to Foo, and maybe they > just don't matter much at run-time. > > Alex > > On 3/6/2013 11:10 PM, michael keith wrote: >> Our usage of the container annotation has fairly consistently been a >> trivial mapping from the singular contained annotation to its pluralized >> containing form. We have, during development, changed the name of the >> singular annotation and then had to go and rename the container >> annotation to the plural form of the newly named singular one, but it >> would not be common at all to decide to rename the container one >> independent of the singular one, and I am talking about development, >> before clients exist. >> >> Existing clients of the current getAnnotation(Class) and >> getAnnotations() methods are written to reference both the repeatable >> and the container annotations directly, so renaming either one of them >> would be a breaking change that we would not generally undertake after >> the annotations have been created/released. >> >> I would not have expected a precompiled client of >> getAnnotationsByType(Foo.class) to be affected by such a change, though. >> The container annotation is meant to be transparent to them, isn't it? >> >> -Mike >> >> On 06/03/2013 8:22 PM, Alex Buckley wrote: >>> Mike, we're pondering whether the new methods in core reflection >>> should be strict about the relationship of containing type to >>> repeatable type. >>> >>> Have you ever written @FooContainer({@Foo(1),...}) on a declartion, >>> and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on >>> clients using getAnnotation(Class) and getAnnotations() would be >>> significant. >>> >>> Effectively we are wondering if a client using >>> getAnnotationsByType(Foo.class) should be affected by such a change. >>> >>> Alex >> From alex.buckley at oracle.com Fri Mar 8 12:44:06 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 08 Mar 2013 12:44:06 -0800 Subject: Question for Mike re: changing containers In-Reply-To: <5139979A.6030205@oracle.com> References: <5137EBF0.1030509@oracle.com> <51383D6D.4070309@oracle.com> <51393969.4070206@oracle.com> <5139979A.6030205@oracle.com> Message-ID: <513A4D96.9050501@oracle.com> On 3/7/2013 11:47 PM, michael keith wrote: > My experience is that the meta-annotations on the container annotation > should match exactly what is on the contained annotation (with the > possible exception that I might only want @Documented to be on @Foo and > not on @FooContainer, if that worked :-). In all other cases I would > expect to be told at compile-time since it is likely an oversight if > they don't match. I don't know that it is that important to catch at > runtime, though, and I would likely opt out of the extra checking if it > cost me some performance. Thanks Mike. We will continue to be strict at compile-time, but will loosen the rules for core reflection so that a container annotation merely needs an array-typed value element; contemporary properties of the containing annotation type (e.g. applicability) will be ignored. Alex From alex.buckley at oracle.com Fri Mar 8 12:45:50 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 08 Mar 2013 12:45:50 -0800 Subject: Strict checking of correctness of containing type by Core Reflection In-Reply-To: <51393541.7090407@oracle.com> References: <51388A2D.7090005@oracle.com> <51393541.7090407@oracle.com> Message-ID: <513A4DFE.5090003@oracle.com> 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 From joel.franck at oracle.com Mon Mar 11 09:23:55 2013 From: joel.franck at oracle.com (=?iso-8859-1?Q?Joel_Borggr=E9n-Franck?=) Date: Mon, 11 Mar 2013 17:23:55 +0100 Subject: Strict checking of correctness of containing type by Core Reflection In-Reply-To: <513A4DFE.5090003@oracle.com> References: <51388A2D.7090005@oracle.com> <51393541.7090407@oracle.com> <513A4DFE.5090003@oracle.com> Message-ID: <1F0B8C41-5DB7-489F-90A1-73EDB5A9E161@oracle.com> Sounds good to me. cheers /Joel On Mar 8, 2013, at 9:45 PM, Alex Buckley 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 From alex.buckley at oracle.com Mon Mar 11 11:19:32 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 11 Mar 2013 11:19:32 -0700 Subject: Strict checking of correctness of containing type by Core Reflection In-Reply-To: <1F0B8C41-5DB7-489F-90A1-73EDB5A9E161@oracle.com> References: <51388A2D.7090005@oracle.com> <51393541.7090407@oracle.com> <513A4DFE.5090003@oracle.com> <1F0B8C41-5DB7-489F-90A1-73EDB5A9E161@oracle.com> Message-ID: <513E2034.4040603@oracle.com> Great. I have updated the spec with the simpler AnnotationFormatError check: http://cr.openjdk.java.net/~abuckley/8misc.pdf Alex On 3/11/2013 9:23 AM, Joel Borggr?n-Franck wrote: > Sounds good to me. > > cheers > /Joel > > On Mar 8, 2013, at 9:45 PM, Alex Buckley 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 > From alex.buckley at oracle.com Mon Mar 11 14:16:13 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 11 Mar 2013 14:16:13 -0700 Subject: @Target annotation with empty set In-Reply-To: <513E41F1.8050502@oracle.com> References: <513E41F1.8050502@oracle.com> Message-ID: <513E499D.8050402@oracle.com> On 3/11/2013 1:43 PM, Jonathan Gibbons wrote: > Is it ever reasonable to have a @Target annotation with an empty set? > > -- Jon > > > import java.lang.annotation.*; > > @Target({}) > @interface TC { T[] value(); } > > @Repeatable(TC.class) > @interface T { } > > @T @T > class C { } Reasonable? No. Legal? Yes. I allude to something like this case in a note in the rep.annos spec: "If Foo has no @Target meta-annotation but FooContainer has an @Target meta-annotation, then @Foo may only be repeated on program elements where @FooContainer may appear." That's fine, and @T should not be able to repeat anywhere. To be clear, TC is a valid containing annotation type for T, because: "T is applicable to at least the same kinds of program element as TC; specifically, If the kinds of program element where T is applicable are represented by the set m1, and the kinds of program element where TC is applicable are represented by the set m2, then each kind in m2 must occur in m1 ..." m2 is the empty set so the clause holds vacuously. @T cannot repeat because: "It is a compile-time error if a declaration is annotated with more than one annotation of a given annotation type, unless the annotation type is repeatable (?9.6), and the annotated declaration is a valid target (?9.6.3.1) of both the repeatable annotation type and the repeatable annotation type's containing annotation type." Alex From steve.sides at oracle.com Mon Mar 11 15:54:13 2013 From: steve.sides at oracle.com (Steve Sides) Date: Mon, 11 Mar 2013 15:54:13 -0700 Subject: @Target annotation with empty set In-Reply-To: <513E499D.8050402@oracle.com> References: <513E41F1.8050502@oracle.com> <513E499D.8050402@oracle.com> Message-ID: <513E6095.9060906@oracle.com> On 3/11/2013 2:16 PM, Alex Buckley wrote: > On 3/11/2013 1:43 PM, Jonathan Gibbons wrote: >> Is it ever reasonable to have a @Target annotation with an empty set? >> >> -- Jon >> >> >> import java.lang.annotation.*; >> >> @Target({}) >> @interface TC { T[] value(); } >> >> @Repeatable(TC.class) >> @interface T { } >> >> @T @T >> class C { } > > Reasonable? No. Legal? Yes. > > I allude to something like this case in a note in the rep.annos spec: > > "If Foo has no @Target meta-annotation but FooContainer has an @Target > meta-annotation, then @Foo may only be repeated on program elements > where @FooContainer may appear." So, is no @Target the same as and empty @Target? -steve > > That's fine, and @T should not be able to repeat anywhere. > > To be clear, TC is a valid containing annotation type for T, because: > > "T is applicable to at least the same kinds of program element as TC; > specifically, If the kinds of program element where T is applicable > are represented by the set m1, and the kinds of program element where > TC is applicable are represented by the set m2, then each kind in m2 > must occur in m1 ..." > > m2 is the empty set so the clause holds vacuously. @T cannot repeat > because: > > "It is a compile-time error if a declaration is annotated with more > than one annotation of a given annotation type, unless the annotation > type is repeatable (?9.6), and the annotated declaration is a valid > target (?9.6.3.1) of both the repeatable annotation type and the > repeatable annotation type's containing annotation type." > > Alex From alex.buckley at oracle.com Mon Mar 11 16:58:58 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 11 Mar 2013 16:58:58 -0700 (PDT) Subject: @Target annotation with empty set Message-ID: <04f98d4d-f8d8-4431-8f58-b041a1f9b24e@default> See the javadoc for java.lang.annotation.Target. No @Target is not the same as an empty @Target. Since 2004. JSR 308 tweaks the meaning of "No @Target", but that can be ignored here. ----- Original Message ----- From: steve.sides at oracle.com To: enhanced-metadata-spec-discuss at openjdk.java.net Sent: Monday, March 11, 2013 3:54:02 PM GMT -08:00 US/Canada Pacific Subject: Re: @Target annotation with empty set On 3/11/2013 2:16 PM, Alex Buckley wrote: > On 3/11/2013 1:43 PM, Jonathan Gibbons wrote: >> Is it ever reasonable to have a @Target annotation with an empty set? >> >> -- Jon >> >> >> import java.lang.annotation.*; >> >> @Target({}) >> @interface TC { T[] value(); } >> >> @Repeatable(TC.class) >> @interface T { } >> >> @T @T >> class C { } > > Reasonable? No. Legal? Yes. > > I allude to something like this case in a note in the rep.annos spec: > > "If Foo has no @Target meta-annotation but FooContainer has an @Target > meta-annotation, then @Foo may only be repeated on program elements > where @FooContainer may appear." So, is no @Target the same as and empty @Target? -steve > > That's fine, and @T should not be able to repeat anywhere. > > To be clear, TC is a valid containing annotation type for T, because: > > "T is applicable to at least the same kinds of program element as TC; > specifically, If the kinds of program element where T is applicable > are represented by the set m1, and the kinds of program element where > TC is applicable are represented by the set m2, then each kind in m2 > must occur in m1 ..." > > m2 is the empty set so the clause holds vacuously. @T cannot repeat > because: > > "It is a compile-time error if a declaration is annotated with more > than one annotation of a given annotation type, unless the annotation > type is repeatable (?9.6), and the annotated declaration is a valid > target (?9.6.3.1) of both the repeatable annotation type and the > repeatable annotation type's containing annotation type." > > Alex From joe.darcy at oracle.com Mon Mar 11 21:06:41 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 11 Mar 2013 21:06:41 -0700 Subject: @Target annotation with empty set In-Reply-To: <513E6095.9060906@oracle.com> References: <513E41F1.8050502@oracle.com> <513E499D.8050402@oracle.com> <513E6095.9060906@oracle.com> Message-ID: <513EA9D1.3030605@oracle.com> On 3/11/2013 3:54 PM, Steve Sides wrote: > On 3/11/2013 2:16 PM, Alex Buckley wrote: >> On 3/11/2013 1:43 PM, Jonathan Gibbons wrote: >>> Is it ever reasonable to have a @Target annotation with an empty set? There is one case where this does what you want: when you want to declare an annotation type that can only be used as the return value for a method in another annotation type. >>> >>> -- Jon >>> >>> >>> import java.lang.annotation.*; >>> >>> @Target({}) >>> @interface TC { T[] value(); } >>> >>> @Repeatable(TC.class) >>> @interface T { } >>> >>> @T @T >>> class C { } >> >> Reasonable? No. Legal? Yes. >> >> I allude to something like this case in a note in the rep.annos spec: >> >> "If Foo has no @Target meta-annotation but FooContainer has an >> @Target meta-annotation, then @Foo may only be repeated on program >> elements where @FooContainer may appear." > So, is no @Target the same as and empty @Target? No; that case is covered in the existing specification. -Joe From pbenedict at apache.org Tue Mar 12 10:47:55 2013 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 12 Mar 2013 12:47:55 -0500 Subject: Repeating annotations and TYPE_USE Message-ID: Since there's no such thing as legacy code for TYPE_USE, should any special consideration be given to always "looking through" the container application for this kind of @Target? Example: public @A @A String foo() { return "foo"; } Paul From alex.buckley at oracle.com Tue Mar 12 12:21:12 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 12 Mar 2013 12:21:12 -0700 Subject: Repeating annotations and TYPE_USE In-Reply-To: References: Message-ID: <513F8028.9070609@oracle.com> Actually there is "legacy code", because JSR 308 defines TYPE_USE as all uses of types plus those locations where TYPE and TYPE_PARAMETER are applicable. The goal is to allow a TYPE annotation type to be broadened to TYPE_USE, but it would be terribly surprising if AnnotatedElement methods on type declarations then started "looking through". Even if TYPE_USE locations were disjoint from other locations, it would still be undesirable to introduce inconsistency in the AnnotatedElement methods. Alex On 3/12/2013 10:47 AM, Paul Benedict wrote: > Since there's no such thing as legacy code for TYPE_USE, should any special > consideration be given to always "looking through" the container > application for this kind of @Target? > > Example: > public @A @A String foo() { return "foo"; } > > Paul > From joel.franck at oracle.com Wed Mar 20 07:02:54 2013 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Wed, 20 Mar 2013 15:02:54 +0100 Subject: getAnnotationsByType() in the presence of both repeating and container Message-ID: Hi Experts, Consider the following declaration in some existing code: @Foo(1) @FooContainer({@Foo(2), @Foo(3)}) class SomeClass {} If the annotation type Foo is converted to be repeatable and FooContainer is the containing type for Foo, we believe that the call SomeClass.class.getAnnotationsByType(Foo.class) is most useful if it returns the array of the merged annotations: [ @Foo(1), @Foo(2), @Foo(3) ] in their natural order (@Foo(1) before @Foo(2) because @Foo(1) occurs before @FooContainer(?) on the declaration). (Of course this should be the case for non-legacy code as well, but we suspect it will be much more common in code dating to before repeating annotations.) Alex pointed out to me that this is currently not according to spec, because: > getAnnotationsByType(Class) relies on the definition of "present", which in turn relies on "directly present", which is: > > "An annotation A is directly present on an element E if ... for an invocation of get[Declared]AnnotationsByType(Class), the attribute either contains A or, if the type of A is repeatable, contains exactly one annotation whose value element contains A and whose type is the containing annotation type of A's type (?9.6)." > > The either-or in this text does not really admit the merging of naked and contained @Foo's. So we propose to change the spec to require this behaviour. My interpretation of the current wording is that the array [ @Foo(1) ] should be returned, but we think this is less useful than the merged array. Due to backward compatibility it is not an option to make the combination an error at reflect time. What do you think? cheers /Joel From alex.buckley at oracle.com Wed Mar 20 12:58:16 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 20 Mar 2013 12:58:16 -0700 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: References: Message-ID: <514A14D8.9070605@oracle.com> On 3/20/2013 7:02 AM, Joel Borggr?n-Franck wrote: > Alex pointed out to me that this is currently not according to spec, > because: > >> getAnnotationsByType(Class) relies on the definition of "present", >> which in turn relies on "directly present", which is: >> >> "An annotation A is directly present on an element E if ... for an >> invocation of get[Declared]AnnotationsByType(Class), the >> attribute either contains A or, if the type of A is repeatable, >> contains exactly one annotation whose value element contains A and >> whose type is the containing annotation type of A's type (?9.6)." >> >> The either-or in this text does not really admit the merging of >> naked and contained @Foo's. Sorry, I read my own words wrong. The definition makes an @Foo annotation be directly present whether it's naked or contained. So, merging is supported already. However, nothing is said about ordering. While what we want is obvious from examples, it's a bit tricky to define it without spelling out possible combinations of annotations. I think the following text should appear in the AnnotatedElement javadoc after the definitions of "directly present" and "present": -- For an invocation of get[Declared]AnnotationsByType(Class), the order of directly present annotations on an element E is computed as if annotations stored in a container annotation on E are stored on E itself, in the order in which they appear in the value element of the container annotation. -- This will work for the language model definitions too - just change "element E" to "construct C" in the javadoc for AnnotatedConstruct. Alex From joe.darcy at oracle.com Wed Mar 20 23:10:34 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 20 Mar 2013 23:10:34 -0700 Subject: Strict checking of correctness of containing type by Core Reflection In-Reply-To: <513E2034.4040603@oracle.com> References: <51388A2D.7090005@oracle.com> <51393541.7090407@oracle.com> <513A4DFE.5090003@oracle.com> <1F0B8C41-5DB7-489F-90A1-73EDB5A9E161@oracle.com> <513E2034.4040603@oracle.com> Message-ID: <514AA45A.3040708@oracle.com> Catching up on email, I'll just note that this laxity in verifying all the compile-time consistency checks at runtime is consistent with the rest of the annotations facility and also consistent with the approach often used in defining binary compatibility. That is, although at runtime it can be possible to detect that a set of inter-dependent types being presented to the JVM would fail to compile together, the JVM in many cases still chooses to load and link the types in question and not throw an error. -Joe On 03/11/2013 11:19 AM, Alex Buckley wrote: > Great. I have updated the spec with the simpler AnnotationFormatError > check: > > http://cr.openjdk.java.net/~abuckley/8misc.pdf > > Alex > > On 3/11/2013 9:23 AM, Joel Borggr?n-Franck wrote: >> Sounds good to me. >> >> cheers >> /Joel >> >> On Mar 8, 2013, at 9:45 PM, Alex Buckley >> 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 >> From joe.darcy at oracle.com Wed Mar 20 23:35:22 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 20 Mar 2013 23:35:22 -0700 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: <514A14D8.9070605@oracle.com> References: <514A14D8.9070605@oracle.com> Message-ID: <514AAA2A.5000102@oracle.com> On 03/20/2013 12:58 PM, Alex Buckley wrote: > On 3/20/2013 7:02 AM, Joel Borggr?n-Franck wrote: >> Alex pointed out to me that this is currently not according to spec, >> because: >> >>> getAnnotationsByType(Class) relies on the definition of "present", >>> which in turn relies on "directly present", which is: >>> >>> "An annotation A is directly present on an element E if ... for an >>> invocation of get[Declared]AnnotationsByType(Class), the >>> attribute either contains A or, if the type of A is repeatable, >>> contains exactly one annotation whose value element contains A and >>> whose type is the containing annotation type of A's type (?9.6)." >>> >>> The either-or in this text does not really admit the merging of >>> naked and contained @Foo's. > > Sorry, I read my own words wrong. The definition makes an @Foo > annotation be directly present whether it's naked or contained. So, > merging is supported already. However, nothing is said about ordering. > > While what we want is obvious from examples, it's a bit tricky to > define it without spelling out possible combinations of annotations. I > think the following text should appear in the AnnotatedElement javadoc > after the definitions of "directly present" and "present": > > -- > For an invocation of get[Declared]AnnotationsByType(Class), the > order of directly present annotations on an element E is computed as > if annotations stored in a container annotation on E are stored on E > itself, in the order in which they appear in the value element of the > container annotation. > -- > > This will work for the language model definitions too - just change > "element E" to "construct C" in the javadoc for AnnotatedConstruct. > > The ordering of inherited annotations should be explicitly specified too. -Joe From alex.buckley at oracle.com Thu Mar 21 14:54:53 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 21 Mar 2013 14:54:53 -0700 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: <514AAA2A.5000102@oracle.com> References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> Message-ID: <514B81AD.8050603@oracle.com> On 3/20/2013 11:35 PM, Joe Darcy wrote: > On 03/20/2013 12:58 PM, Alex Buckley wrote: >> While what we want is obvious from examples, it's a bit tricky to >> define it without spelling out possible combinations of annotations. I >> think the following text should appear in the AnnotatedElement javadoc >> after the definitions of "directly present" and "present": >> >> -- >> For an invocation of get[Declared]AnnotationsByType(Class), the >> order of directly present annotations on an element E is computed as >> if annotations stored in a container annotation on E are stored on E >> itself, in the order in which they appear in the value element of the >> container annotation. >> -- >> >> This will work for the language model definitions too - just change >> "element E" to "construct C" in the javadoc for AnnotatedConstruct. > > The ordering of inherited annotations should be explicitly specified too. This is basically taken care of by the "present" rule which builds on "directly present". If you have a simple case of inheritance: @Foo(0) @FooContainer({@Foo(1), at Foo(2)}) class A {} class B extends A {} then B.class.getAnnotationsByType(Foo.class) will return the "present" annotations on B, which reduce to the "directly present" annotations on A, which is a previously solved problem. The policy of subclass annotations overriding superclass annotations means that ordering across the class hierarchy should never be an issue. So if you have a complex case of inheritance: @Foo(0) class A {} @FooContainer({@Foo(1), at Foo(2)}) @Foo(3) class B extends A {} then B.class.getAnnotationsByType(Foo.class) should consider only the @Foo's present on B, whose order is a previously solved problem. Alex P.S. I realized that the definition of "present": - An annotation A is present on an element E if either: - A is directly present on E; or - A is not directly present on E, and E is a class, ... is wrong because it makes @Foo(0) on A be present on B - but B's own @Foo's are meant to take precedence. The second clause was meant to be about a broad class of things, not a specific thing: - 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, ... I'm pretty sure this latter definition is what got implemented, because examples 1.2-4 and 1.2-5 in the spec do the right thing and have been tested on the RI. From ali.ebrahimi1781 at gmail.com Thu Mar 21 15:19:54 2013 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Fri, 22 Mar 2013 02:49:54 +0430 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: <514B81AD.8050603@oracle.com> References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> <514B81AD.8050603@oracle.com> Message-ID: Hi Alex, please clarify following scenarios: 1) @Foo(0) @Foo(1) class A {} @Foo(2) @Foo(3) class B extends A {} B.class.getAnnotationsByType(Foo.class)? 2) @FooContainer({@Foo(0), at Foo(1)}) class A {} @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} B.class.getAnnotationsByType(Foo.class)? 3) @Foo(0) @Foo(1) class A {} @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} B.class.getAnnotationsByType(Foo.class)? 4) @FooContainer({@Foo(0), at Foo(1)}) class A {} @Foo(2) @Foo(3) class B extends A {} B.class.getAnnotationsByType(Foo.class)? Regards, Ali Ebrahimi On Fri, Mar 22, 2013 at 2:24 AM, Alex Buckley wrote: > On 3/20/2013 11:35 PM, Joe Darcy wrote: > >> On 03/20/2013 12:58 PM, Alex Buckley wrote: >> >>> While what we want is obvious from examples, it's a bit tricky to >>> define it without spelling out possible combinations of annotations. I >>> think the following text should appear in the AnnotatedElement javadoc >>> after the definitions of "directly present" and "present": >>> >>> -- >>> For an invocation of get[Declared]**AnnotationsByType(Class), the >>> order of directly present annotations on an element E is computed as >>> if annotations stored in a container annotation on E are stored on E >>> itself, in the order in which they appear in the value element of the >>> container annotation. >>> -- >>> >>> This will work for the language model definitions too - just change >>> "element E" to "construct C" in the javadoc for AnnotatedConstruct. >>> >> >> The ordering of inherited annotations should be explicitly specified too. >> > > This is basically taken care of by the "present" rule which builds on > "directly present". > > If you have a simple case of inheritance: > > @Foo(0) @FooContainer({@Foo(1), at Foo(2)**}) class A {} > class B extends A {} > > then B.class.getAnnotationsByType(**Foo.class) will return the "present" > annotations on B, which reduce to the "directly present" annotations on A, > which is a previously solved problem. > > The policy of subclass annotations overriding superclass annotations means > that ordering across the class hierarchy should never be an issue. So if > you have a complex case of inheritance: > > @Foo(0) class A {} > @FooContainer({@Foo(1), at Foo(2)**}) @Foo(3) class B extends A {} > > then B.class.getAnnotationsByType(**Foo.class) should consider only the > @Foo's present on B, whose order is a previously solved problem. > > Alex > > P.S. I realized that the definition of "present": > > - An annotation A is present on an element E if either: > - A is directly present on E; or > - A is not directly present on E, and E is a class, ... > > is wrong because it makes @Foo(0) on A be present on B - but B's own > @Foo's are meant to take precedence. The second clause was meant to be > about a broad class of things, not a specific thing: > > - 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, > ... > > I'm pretty sure this latter definition is what got implemented, because > examples 1.2-4 and 1.2-5 in the spec do the right thing and have been > tested on the RI. > From ali.ebrahimi1781 at gmail.com Thu Mar 21 15:31:18 2013 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Fri, 22 Mar 2013 03:01:18 +0430 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> <514B81AD.8050603@oracle.com> Message-ID: Hi again Alex, and this scenarios: 5) @Foo(0) @Foo(1) @FooContainer({@Foo(01), at Foo(11) }) class A {} @Foo(2) @Foo(3) class B extends A {} B.class.getAnnotationsByType(Foo.class)? 6) @FooContainer({@Foo(0), at Foo(1)}) class A {} @Foo(02) @Foo(03) @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} B.class.getAnnotationsByType(Foo.class)? Regards, Ali Ebrahimi On Fri, Mar 22, 2013 at 2:24 AM, Alex Buckley wrote: > On 3/20/2013 11:35 PM, Joe Darcy wrote: > >> On 03/20/2013 12:58 PM, Alex Buckley wrote: >> >>> While what we want is obvious from examples, it's a bit tricky to >>> define it without spelling out possible combinations of annotations. I >>> think the following text should appear in the AnnotatedElement javadoc >>> after the definitions of "directly present" and "present": >>> >>> -- >>> For an invocation of get[Declared]**AnnotationsByType(Class), the >>> order of directly present annotations on an element E is computed as >>> if annotations stored in a container annotation on E are stored on E >>> itself, in the order in which they appear in the value element of the >>> container annotation. >>> -- >>> >>> This will work for the language model definitions too - just change >>> "element E" to "construct C" in the javadoc for AnnotatedConstruct. >>> >> >> The ordering of inherited annotations should be explicitly specified too. >> > > This is basically taken care of by the "present" rule which builds on > "directly present". > > If you have a simple case of inheritance: > > @Foo(0) @FooContainer({@Foo(1), at Foo(2)**}) class A {} > class B extends A {} > > then B.class.getAnnotationsByType(**Foo.class) will return the "present" > annotations on B, which reduce to the "directly present" annotations on A, > which is a previously solved problem. > > The policy of subclass annotations overriding superclass annotations means > that ordering across the class hierarchy should never be an issue. So if > you have a complex case of inheritance: > > @Foo(0) class A {} > @FooContainer({@Foo(1), at Foo(2)**}) @Foo(3) class B extends A {} > > then B.class.getAnnotationsByType(**Foo.class) should consider only the > @Foo's present on B, whose order is a previously solved problem. > > Alex > > P.S. I realized that the definition of "present": > > - An annotation A is present on an element E if either: > - A is directly present on E; or > - A is not directly present on E, and E is a class, ... > > is wrong because it makes @Foo(0) on A be present on B - but B's own > @Foo's are meant to take precedence. The second clause was meant to be > about a broad class of things, not a specific thing: > > - 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, > ... > > I'm pretty sure this latter definition is what got implemented, because > examples 1.2-4 and 1.2-5 in the spec do the right thing and have been > tested on the RI. > From alex.buckley at oracle.com Thu Mar 21 16:03:21 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 21 Mar 2013 16:03:21 -0700 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> <514B81AD.8050603@oracle.com> Message-ID: <514B91B9.9010408@oracle.com> In every case, the answer and reason is the same: @Foo(2) @Foo(3) (in that order) because while @Foo(0) and @Foo(1) are directly present on A, the fact that even one annotation of type Foo is directly present on B means that @Foo(0) and @Foo(1) are not present on B. (This is the overriding policy we always intended, and which is now correctly embodied by the "present" rule.) Alex On 3/21/2013 3:19 PM, Ali Ebrahimi wrote: > Hi Alex, > please clarify following scenarios: > > 1) > > @Foo(0) @Foo(1) class A {} > @Foo(2) @Foo(3) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > > 2) > @FooContainer({@Foo(0), at Foo(1)}) class A {} > @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > > 3) > > @Foo(0) @Foo(1) class A {} > @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > 4) > @FooContainer({@Foo(0), at Foo(1)}) class A {} > @Foo(2) @Foo(3) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > > Regards, > Ali Ebrahimi > On Fri, Mar 22, 2013 at 2:24 AM, Alex Buckley > wrote: > > On 3/20/2013 11:35 PM, Joe Darcy wrote: > > On 03/20/2013 12:58 PM, Alex Buckley wrote: > > While what we want is obvious from examples, it's a bit > tricky to > define it without spelling out possible combinations of > annotations. I > think the following text should appear in the > AnnotatedElement javadoc > after the definitions of "directly present" and "present": > > -- > For an invocation of > get[Declared]__AnnotationsByType(Class), the > order of directly present annotations on an element E is > computed as > if annotations stored in a container annotation on E are > stored on E > itself, in the order in which they appear in the value > element of the > container annotation. > -- > > This will work for the language model definitions too - just > change > "element E" to "construct C" in the javadoc for > AnnotatedConstruct. > > > The ordering of inherited annotations should be explicitly > specified too. > > > This is basically taken care of by the "present" rule which builds > on "directly present". > > If you have a simple case of inheritance: > > @Foo(0) @FooContainer({@Foo(1), at Foo(2)__}) class A {} > class B extends A {} > > then B.class.getAnnotationsByType(__Foo.class) will return the > "present" annotations on B, which reduce to the "directly present" > annotations on A, which is a previously solved problem. > > The policy of subclass annotations overriding superclass annotations > means that ordering across the class hierarchy should never be an > issue. So if you have a complex case of inheritance: > > @Foo(0) class A {} > @FooContainer({@Foo(1), at Foo(2)__}) @Foo(3) class B extends A {} > > then B.class.getAnnotationsByType(__Foo.class) should consider only > the @Foo's present on B, whose order is a previously solved problem. > > Alex > > P.S. I realized that the definition of "present": > > - An annotation A is present on an element E if either: > - A is directly present on E; or > - A is not directly present on E, and E is a class, ... > > is wrong because it makes @Foo(0) on A be present on B - but B's own > @Foo's are meant to take precedence. The second clause was meant to > be about a broad class of things, not a specific thing: > > - 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, ... > > I'm pretty sure this latter definition is what got implemented, > because examples 1.2-4 and 1.2-5 in the spec do the right thing and > have been tested on the RI. > > From alex.buckley at oracle.com Thu Mar 21 16:05:57 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 21 Mar 2013 16:05:57 -0700 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> <514B81AD.8050603@oracle.com> Message-ID: <514B9255.1040404@oracle.com> Both cases are illegal because: It is a compile-time error if a declaration is annotated with more than one annotation of a repeatable annotation type T and any annotations of the containing annotation type of T. The reason is exhaustively discussed in section 9.7 of the spec. Alex On 3/21/2013 3:31 PM, Ali Ebrahimi wrote: > Hi again Alex, > and this scenarios: > > 5) > > @Foo(0) @Foo(1) @FooContainer({@Foo(01), at Foo(11) > }) class A {} > @Foo(2) @Foo(3) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > > 6) > @FooContainer({@Foo(0), at Foo(1)}) class A {} > @Foo(02) @Foo(03) @FooContainer({@Foo(2), at Foo(3)}) class B extends A {} > > B.class.getAnnotationsByType(Foo.class)? > > > Regards, > Ali Ebrahimi > > On Fri, Mar 22, 2013 at 2:24 AM, Alex Buckley > wrote: > > On 3/20/2013 11:35 PM, Joe Darcy wrote: > > On 03/20/2013 12:58 PM, Alex Buckley wrote: > > While what we want is obvious from examples, it's a bit > tricky to > define it without spelling out possible combinations of > annotations. I > think the following text should appear in the > AnnotatedElement javadoc > after the definitions of "directly present" and "present": > > -- > For an invocation of > get[Declared]__AnnotationsByType(Class), the > order of directly present annotations on an element E is > computed as > if annotations stored in a container annotation on E are > stored on E > itself, in the order in which they appear in the value > element of the > container annotation. > -- > > This will work for the language model definitions too - just > change > "element E" to "construct C" in the javadoc for > AnnotatedConstruct. > > > The ordering of inherited annotations should be explicitly > specified too. > > > This is basically taken care of by the "present" rule which builds > on "directly present". > > If you have a simple case of inheritance: > > @Foo(0) @FooContainer({@Foo(1), at Foo(2)__}) class A {} > class B extends A {} > > then B.class.getAnnotationsByType(__Foo.class) will return the > "present" annotations on B, which reduce to the "directly present" > annotations on A, which is a previously solved problem. > > The policy of subclass annotations overriding superclass annotations > means that ordering across the class hierarchy should never be an > issue. So if you have a complex case of inheritance: > > @Foo(0) class A {} > @FooContainer({@Foo(1), at Foo(2)__}) @Foo(3) class B extends A {} > > then B.class.getAnnotationsByType(__Foo.class) should consider only > the @Foo's present on B, whose order is a previously solved problem. > > Alex > > P.S. I realized that the definition of "present": > > - An annotation A is present on an element E if either: > - A is directly present on E; or > - A is not directly present on E, and E is a class, ... > > is wrong because it makes @Foo(0) on A be present on B - but B's own > @Foo's are meant to take precedence. The second clause was meant to > be about a broad class of things, not a specific thing: > > - 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, ... > > I'm pretty sure this latter definition is what got implemented, > because examples 1.2-4 and 1.2-5 in the spec do the right thing and > have been tested on the RI. > > > From ali.ebrahimi1781 at gmail.com Thu Mar 21 22:12:06 2013 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Fri, 22 Mar 2013 09:42:06 +0430 Subject: getAnnotationsByType() in the presence of both repeating and container In-Reply-To: <514B9255.1040404@oracle.com> References: <514A14D8.9070605@oracle.com> <514AAA2A.5000102@oracle.com> <514B81AD.8050603@oracle.com> <514B9255.1040404@oracle.com> Message-ID: Thanks. On Fri, Mar 22, 2013 at 3:35 AM, Alex Buckley wrote: > Both cases are illegal because: > > It is a compile-time error if a declaration is annotated with more than > one annotation of a repeatable annotation type T and any annotations of the > containing annotation type of T. > > The reason is exhaustively discussed in section 9.7 of the spec. > > Alex > > > On 3/21/2013 3:31 PM, Ali Ebrahimi wrote: > >> Hi again Alex, >> and this scenarios: >> >> 5) >> >> @Foo(0) @Foo(1) @FooContainer({@Foo(01), at Foo(**11) >> }) class A {} >> @Foo(2) @Foo(3) class B extends A {} >> >> B.class.getAnnotationsByType(**Foo.class)? >> >> >> 6) >> @FooContainer({@Foo(0), at Foo(1)**}) class A {} >> @Foo(02) @Foo(03) @FooContainer({@Foo(2), at Foo(3)**}) class B extends A >> {} >> >> B.class.getAnnotationsByType(**Foo.class)? >> >> >> Regards, >> Ali Ebrahimi >> >> On Fri, Mar 22, 2013 at 2:24 AM, Alex Buckley > >> wrote: >> >> On 3/20/2013 11:35 PM, Joe Darcy wrote: >> >> On 03/20/2013 12:58 PM, Alex Buckley wrote: >> >> While what we want is obvious from examples, it's a bit >> tricky to >> define it without spelling out possible combinations of >> annotations. I >> think the following text should appear in the >> AnnotatedElement javadoc >> after the definitions of "directly present" and "present": >> >> -- >> For an invocation of >> get[Declared]__**AnnotationsByType(Class), the >> >> order of directly present annotations on an element E is >> computed as >> if annotations stored in a container annotation on E are >> stored on E >> itself, in the order in which they appear in the value >> element of the >> container annotation. >> -- >> >> This will work for the language model definitions too - just >> change >> "element E" to "construct C" in the javadoc for >> AnnotatedConstruct. >> >> >> The ordering of inherited annotations should be explicitly >> specified too. >> >> >> This is basically taken care of by the "present" rule which builds >> on "directly present". >> >> If you have a simple case of inheritance: >> >> @Foo(0) @FooContainer({@Foo(1), at Foo(2)**__}) class A {} >> class B extends A {} >> >> then B.class.getAnnotationsByType(_**_Foo.class) will return the >> >> "present" annotations on B, which reduce to the "directly present" >> annotations on A, which is a previously solved problem. >> >> The policy of subclass annotations overriding superclass annotations >> means that ordering across the class hierarchy should never be an >> issue. So if you have a complex case of inheritance: >> >> @Foo(0) class A {} >> @FooContainer({@Foo(1), at Foo(2)**__}) @Foo(3) class B extends A {} >> >> then B.class.getAnnotationsByType(_**_Foo.class) should consider only >> >> the @Foo's present on B, whose order is a previously solved problem. >> >> Alex >> >> P.S. I realized that the definition of "present": >> >> - An annotation A is present on an element E if either: >> - A is directly present on E; or >> - A is not directly present on E, and E is a class, ... >> >> is wrong because it makes @Foo(0) on A be present on B - but B's own >> @Foo's are meant to take precedence. The second clause was meant to >> be about a broad class of things, not a specific thing: >> >> - 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, ... >> >> I'm pretty sure this latter definition is what got implemented, >> because examples 1.2-4 and 1.2-5 in the spec do the right thing and >> have been tested on the RI. >> >> >> >> From joe.darcy at oracle.com Tue Mar 26 16:10:50 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 26 Mar 2013 16:10:50 -0700 Subject: Request for revised terminology describing ways annotations can be present or not Message-ID: <51522AFA.4070906@oracle.com> Hello, The JSR 296 API includes both a language model (javax.lang.model.*) and an API to define and interact with annotation processors (javax.annotation.processing). The language model portion of the API has already been updated for repeating annotations by the addition of some new method which perform the container look through operations. With my JSR 269 maintenance lead hat on, I've started looking at how the annotation processing portion of the API should be amended to address repeating annotations. In brief, and processing API requires that the set of annotations present on a body of code be computed. To preserve behavioral compatibility, "present" in this context means directly present in the source code or class file representation of a declaration or present via inheritance. Container look-through should *not* be considered. I was hoping to describe this arrangement using the "directly present" and "present" terminology from java.lang.reflect.AnnotatedElement or javax.lang.model.AnnotatedConstruct. Unfortunately, those terms allow look though to occur based on which method is being called. So what I'd like to have is a set of definition in the AnnotatedElement/AnnotatedConstruct types which support the following distinctions: 1) directly present (no inheritance, no container look through) 2) present directly or present indirectly via inheritance 3) present directly or present indirectly via container look through 4) present directly or via the supported interaction of inheritance and look through Thanks, -Joe From alex.buckley at oracle.com Tue Mar 26 20:09:57 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 26 Mar 2013 20:09:57 -0700 Subject: Request for revised terminology describing ways annotations can be present or not In-Reply-To: <51522AFA.4070906@oracle.com> References: <51522AFA.4070906@oracle.com> Message-ID: <51526305.2040804@oracle.com> On 3/26/2013 4:10 PM, Joe Darcy wrote: > In brief, and processing API requires that the set of annotations > present on a body of code be computed. To preserve behavioral > compatibility, "present" in this context means directly present in the > source code or class file representation of a declaration or present via > inheritance. Container look-through should *not* be considered. > > I was hoping to describe this arrangement using the "directly present" > and "present" terminology from java.lang.reflect.AnnotatedElement or > javax.lang.model.AnnotatedConstruct. Unfortunately, those terms allow > look though to occur based on which method is being called. > > So what I'd like to have is a set of definition in the > AnnotatedElement/AnnotatedConstruct types which support the following > distinctions: > > 1) directly present (no inheritance, no container look through) > 2) present directly or present indirectly via inheritance > 3) present directly or present indirectly via container look through > 4) present directly or via the supported interaction of inheritance and > look through The building blocks are easy: a) An annotation A is DIRECTLY PRESENT on an element E if E is associated with a RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations attribute, and the attribute contains A. b) An annotation A is INDIRECTLY PRESENT on an element E if E is associated with a RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations attribute, and A's type is repeatable, and E contains exactly one annotation whose value element contains A and whose type is the containing annotation type of A's type (?9.6). The trouble is PRESENT. If it's an SE7-era PRESENT - aware of inheritance but not containment - then it's very hard to find a term for an SE8-era PRESENT which knows both inheritance and containment. Still, let's start with an SE7-era PRESENT and see what happens: c) 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. The javadoc for getDeclaredAnnotationsByType(Class) can simply say: "Returns the annotations which are directly or indirectly present on this element." The javadoc for getAnnotationsByType(Class) will have to embody a recursive-lookup-with-overriding policy: "Returns the annotations which are directly or indirectly present on this element. If there are none, then if this element is a class, returns the annotations of inheritable type which are returned by an invocation of getAnnotationsByType(Class) on the superclass of this element." Yuk. This operational description is patterned after (c)'s definition of PRESENT, but you'd never guess that. I'm going to bite the bullet and introduce a new term: d) 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. The similarity of PRESENT and ASSOCIATED is clear. getAnnotationsByType(Class) is just: "Returns the annotations which are associated with this element." If that sounds OK, I'll modify the spec PDF and file a bug to change the core reflection and language model javadocs. No changes should be needed in any method implementation. Alex From joe.darcy at oracle.com Thu Mar 28 18:20:58 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 28 Mar 2013 18:20:58 -0700 Subject: Request for revised terminology describing ways annotations can be present or not In-Reply-To: <51526305.2040804@oracle.com> References: <51522AFA.4070906@oracle.com> <51526305.2040804@oracle.com> Message-ID: <5154EC7A.6010700@oracle.com> Hello, To provide some context, here is an excerpt from the javax.annotation.processing.Processor interfaces which describes part of the tool <-> processor protocol: "The tool uses a discovery process to find annotation processors and decide whether or not they should be run. [...] Which processors the tool asks to run is a function of what annotations are present on the root elements, what annotation types a processor processes, and whether or not a processor claims the annotations it processes. [...] For a given round, the tool computes the set of annotation types on the root elements. If there is at least one annotation type present, as processors claim annotation types, they are removed from the set of unmatched annotations." To this, I will add a paragraph explaining how repeating annotations affect this discovery process. "

An annotation type is considered present if there is at least one annotation of that type on a declaration enclosed within the root elements of a round. For this purpose, a type parameter is considered to be enclosed by its generic element. Annotations on type uses are not considered as part of the computation. An annotation is present on a declaration if it is present as defined in {@link AnnotatedConstruct}. That is, the annotation may be directly present or present via inheritance. An annotation indirectly present by virtue of a repeatable annotation type is not considered represent for the purposes of the discovery process. Therefore, to properly process repeatable annotation types, processors are advised to include both the annotation and its container in the set of {@linkplain #getSupportedAnnotationTypes() supported annotation types}." Thanks, -Joe On 03/26/2013 08:09 PM, Alex Buckley wrote: > On 3/26/2013 4:10 PM, Joe Darcy wrote: >> In brief, and processing API requires that the set of annotations >> present on a body of code be computed. To preserve behavioral >> compatibility, "present" in this context means directly present in the >> source code or class file representation of a declaration or present via >> inheritance. Container look-through should *not* be considered. >> >> I was hoping to describe this arrangement using the "directly present" >> and "present" terminology from java.lang.reflect.AnnotatedElement or >> javax.lang.model.AnnotatedConstruct. Unfortunately, those terms allow >> look though to occur based on which method is being called. >> >> So what I'd like to have is a set of definition in the >> AnnotatedElement/AnnotatedConstruct types which support the following >> distinctions: >> >> 1) directly present (no inheritance, no container look through) >> 2) present directly or present indirectly via inheritance >> 3) present directly or present indirectly via container look through >> 4) present directly or via the supported interaction of inheritance and >> look through > > The building blocks are easy: > > a) An annotation A is DIRECTLY PRESENT on an element E if E is > associated with a RuntimeVisibleAnnotations or > RuntimeVisibleParameterAnnotations attribute, and the attribute > contains A. > > b) An annotation A is INDIRECTLY PRESENT on an element E if E is > associated with a RuntimeVisibleAnnotations or > RuntimeVisibleParameterAnnotations attribute, and A's type is > repeatable, and E contains exactly one annotation whose value element > contains A and whose type is the containing annotation type of A's > type (?9.6). > > The trouble is PRESENT. If it's an SE7-era PRESENT - aware of > inheritance but not containment - then it's very hard to find a term > for an SE8-era PRESENT which knows both inheritance and containment. > Still, let's start with an SE7-era PRESENT and see what happens: > > c) 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. > > The javadoc for getDeclaredAnnotationsByType(Class) can simply say: > > "Returns the annotations which are directly or indirectly present on > this element." > > The javadoc for getAnnotationsByType(Class) will have to embody a > recursive-lookup-with-overriding policy: > > "Returns the annotations which are directly or indirectly present on > this element. If there are none, then if this element is a class, > returns the annotations of inheritable type which are returned by an > invocation of getAnnotationsByType(Class) on the superclass of this > element." > > Yuk. This operational description is patterned after (c)'s definition > of PRESENT, but you'd never guess that. I'm going to bite the bullet > and introduce a new term: > > d) 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. > > The similarity of PRESENT and ASSOCIATED is clear. > getAnnotationsByType(Class) is just: > > "Returns the annotations which are associated with this element." > > If that sounds OK, I'll modify the spec PDF and file a bug to change > the core reflection and language model javadocs. No changes should be > needed in any method implementation. > > Alex