From pbenedict at apache.org Wed Jan 2 07:22:22 2013 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 2 Jan 2013 09:22:22 -0600 Subject: A simpler model for repeating annotations Message-ID: I like the new proposal better. Yet, there's one thing that bothers me, which is the naming of get[Declared]Annotations(Foo.class). It's way too easy to look at the API and miss the difference in behavior here. I propose giving it this name: get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for language model's new typed method. Paul From pbenedict at apache.org Wed Jan 2 07:32:28 2013 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 2 Jan 2013 09:32:28 -0600 Subject: A simpler model for repeating annotations In-Reply-To: References: Message-ID: BTW, I read something by Remi a few days back that was quite interesting. It was from another thread. He said that correct method overloading is not supposed to change behavior. Given that bit of wisdom, that's why I recommend a renaming here. Behavior is changing, thus a new name should be given. On Wed, Jan 2, 2013 at 9:22 AM, Paul Benedict wrote: > I like the new proposal better. Yet, there's one thing that bothers > me, which is the naming of get[Declared]Annotations(Foo.class). It's > way too easy to look at the API and miss the difference in behavior > here. I propose giving it this name: > get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for > language model's new typed method. > > Paul From alex.buckley at oracle.com Wed Jan 2 17:46:31 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 02 Jan 2013 17:46:31 -0800 Subject: A simpler model for repeating annotations In-Reply-To: References: Message-ID: <50E4E2F7.4060704@oracle.com> Having spent today writing out the expected behavior of core reflection methods, I'm sympathetic to the idea that get[Declared]Annotations(Class) should be more clearly distinguished. I've avoided the term "repeating" in API names since repetition is not really the point - the point is multiple applications of the same annotation type, but "multiple" has its own downsides since there may only be one annotation for the new methods to return. I'd favor something more like getAll[Declared]Annotations(Class). Comments welcome. Alex On 1/2/2013 7:32 AM, Paul Benedict wrote: > BTW, I read something by Remi a few days back that was quite > interesting. It was from another thread. He said that correct method > overloading is not supposed to change behavior. Given that bit of > wisdom, that's why I recommend a renaming here. Behavior is changing, > thus a new name should be given. > > On Wed, Jan 2, 2013 at 9:22 AM, Paul Benedict wrote: >> I like the new proposal better. Yet, there's one thing that bothers >> me, which is the naming of get[Declared]Annotations(Foo.class). It's >> way too easy to look at the API and miss the difference in behavior >> here. I propose giving it this name: >> get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for >> language model's new typed method. >> >> Paul From forax at univ-mlv.fr Thu Jan 3 02:40:51 2013 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 03 Jan 2013 11:40:51 +0100 Subject: A simpler model for repeating annotations In-Reply-To: <50E4E2F7.4060704@oracle.com> References: <50E4E2F7.4060704@oracle.com> Message-ID: <50E56033.7020906@univ-mlv.fr> On 01/03/2013 02:46 AM, Alex Buckley wrote: > Having spent today writing out the expected behavior of core > reflection methods, I'm sympathetic to the idea that > get[Declared]Annotations(Class) should be more clearly distinguished. > I've avoided the term "repeating" in API names since repetition is not > really the point - the point is multiple applications of the same > annotation type, but "multiple" has its own downsides since there may > only be one annotation for the new methods to return. I'd favor > something more like getAll[Declared]Annotations(Class). Comments welcome. > > Alex yes, getAll* is Ok for me. R?mi > > On 1/2/2013 7:32 AM, Paul Benedict wrote: >> BTW, I read something by Remi a few days back that was quite >> interesting. It was from another thread. He said that correct method >> overloading is not supposed to change behavior. Given that bit of >> wisdom, that's why I recommend a renaming here. Behavior is changing, >> thus a new name should be given. >> >> On Wed, Jan 2, 2013 at 9:22 AM, Paul Benedict >> wrote: >>> I like the new proposal better. Yet, there's one thing that bothers >>> me, which is the naming of get[Declared]Annotations(Foo.class). It's >>> way too easy to look at the API and miss the difference in behavior >>> here. I propose giving it this name: >>> get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for >>> language model's new typed method. >>> >>> Paul From joel.franck at oracle.com Thu Jan 3 04:40:39 2013 From: joel.franck at oracle.com (=?ISO-8859-1?Q?Joel_Borggr=E9n-Franck?=) Date: Thu, 03 Jan 2013 13:40:39 +0100 Subject: A simpler model for repeating annotations In-Reply-To: <50E4E2F7.4060704@oracle.com> References: <50E4E2F7.4060704@oracle.com> Message-ID: <50E57C47.10107@oracle.com> On 01/03/2013 02:46 AM, Alex Buckley wrote: > Having spent today writing out the expected behavior of core reflection > methods, I'm sympathetic to the idea that get[Declared]Annotations(Class) > should be more clearly distinguished. I've avoided the term "repeating" in > API names since repetition is not really the point - the point is multiple > applications of the same annotation type, but "multiple" has its own > downsides since there may only be one annotation for the new methods to > return. I'd favor something more like getAll[Declared]Annotations(Class). > Comments welcome. > getAll* sounds reasonable. cheers /Joel From alex.buckley at oracle.com Thu Jan 3 14:04:07 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 03 Jan 2013 14:04:07 -0800 Subject: A simpler model for repeating annotations In-Reply-To: <50DDFE46.6010106@oracle.com> References: <50DDFE46.6010106@oracle.com> Message-ID: <50E60057.9040505@oracle.com> I have updated the spec at http://cr.openjdk.java.net/~abuckley/8misc.pdf to reflect the model below. Alex On 12/28/2012 12:17 PM, Alex Buckley wrote: > Feedback from Java EE architects indicates a strong preference for 100% > behavioral compatibility for legacy core reflection methods. > > Summarizing Mike Keith's comments: 1) getAnnotation(Class) must not > return one @Foo annotation if multiple @Foo annotations were present in > source, and 2) getAnnotations() must not return multiple @Foo > annotations if they present in source. > > These requirements imply keeping containment at the heart of > repeatability. Why? Assume there were no containers, and you could > simply write: > > @Repeatable @interface Foo {} > > such that @Foo @Foo on class A is compiled directly into A.class. This > scheme would impose high complexity on legacy core reflection methods. > getAnnotation(Foo.class) would have to read _all_ annotations (declared > and inherited) to detect multiple @Foo annotations then return null or > throw an exception. (Remember, returning one of the multiple annotations > is "wrong".) getAnnotations() would have similar trouble deciding what > to return if multiple @Foo annotations are found. In essence, the legacy > core reflection methods are morally incompatible with uncontained > multiple annotations. The solution is to compile multiple annotations > with containers, and have the legacy core reflection methods behave > identically to Java SE 7 (no look through). > > To support new reflective clients who understand repeating annotations, > we can keep the previously-proposed getAnnotations(Class) which looks > through containers. That is, getAnnotations(Foo.class) returns @Foo @Foo > because it a) detects that Foo.class is a repeatable annotation type > with a containing annotation type of FooContainer, then b) looks through > any @FooContainer present. > > It is clear that a repeatable annotation type must still nominate its > containing annotation type, but the reverse is no longer true. That is, > the declaration of FooContainer no longer needs to say > @ContainerFor(Foo.class). This is a direct consequence of dropping look > through for the legacy core reflection methods. Also, the difficult > question about calling getAnnotations() on a subclass - should it look > through an inherited container, or return it? - goes away, as normal > overriding policy gives good answers. > > Here's a simple model that Joe, Joel, and I are happy with: > > - @Repeatable(FooContainer.class) on @interface Foo {} causes > @Foo @Foo in source to be containerized in the class file. > (Rename @ContainedBy to @Repeatable.) > > - The rules for a well-formed relationship between Foo and > FooContainer remain. > > - Core reflection's legacy methods return what's in the class file: > - get[Declared]Annotation(Foo.class) returns nothing, like today. > - get[Declared]Annotations() returns @FooContainer, like today. > > - Core reflection's new typed methods look through containers: > - get[Declared]Annotations(Foo.class) returns @Foo @Foo. > > - An annotation writer may manually rewrite @FooContainer(...) as > @Foo @Foo, and it will be containerized with perfect compatibility. > > - Language model's legacy methods follow core reflection: > - Element.getAnnotation(Foo.class) returns nothing, like today. > - Element[s].get[All]AnnotationMirrors() returns @FooContainer, like > today > > - Language model's new typed method looks through: > - Element.getAnnotations(Foo.class) returns @Foo @Foo. > - We may add Element.getAnnotationMirrors(TypeElement) in future. > > I think the reduced semantic burden for an annotation type owner (no > more @ContainedFor) and the stronger compatibility story for an > annotation reader (no look through for legacy methods) are real > improvements. We will specify and implement the model over the next month. > > Alex From michael.keith at oracle.com Mon Jan 7 08:55:36 2013 From: michael.keith at oracle.com (michael keith) Date: Mon, 07 Jan 2013 11:55:36 -0500 Subject: A simpler model for repeating annotations In-Reply-To: <50E4E2F7.4060704@oracle.com> References: <50E4E2F7.4060704@oracle.com> Message-ID: <50EAFE08.2040808@oracle.com> Thanks for the update, Alex. I like the direction this is going in. Since the get[Declared]Annotations(Class) methods are semantically different from the others they do deserve something different in their names to indicate it. However, given that the javadoc of the lagacy get[Declared]Annotations() methods state simply "Returns *all* annotations [directly] present on this element" (emphasis added) I am not sure that adding "All" to the semantically different get[Declared]Annotations(Class) pair is going to be a very good differentiator. Maybe "multiple" could be used in a different way, for example: get[Declared]AnnotationsWithMultiples? Also, I was just wondering if the getDeclaredAnnotation(Class) method will be considered a backfilled "new legacy" method and have similar semantics to getAnnotation(Class), or will it look through? If it looks through then it should be renamed as well and we might want to reconsider what the name of the method variant is. -Mike On 02/01/2013 8:46 PM, Alex Buckley wrote: > Having spent today writing out the expected behavior of core > reflection methods, I'm sympathetic to the idea that > get[Declared]Annotations(Class) should be more clearly distinguished. > I've avoided the term "repeating" in API names since repetition is not > really the point - the point is multiple applications of the same > annotation type, but "multiple" has its own downsides since there may > only be one annotation for the new methods to return. I'd favor > something more like getAll[Declared]Annotations(Class). Comments welcome. > > Alex > > On 1/2/2013 7:32 AM, Paul Benedict wrote: >> BTW, I read something by Remi a few days back that was quite >> interesting. It was from another thread. He said that correct method >> overloading is not supposed to change behavior. Given that bit of >> wisdom, that's why I recommend a renaming here. Behavior is changing, >> thus a new name should be given. >> >> On Wed, Jan 2, 2013 at 9:22 AM, Paul Benedict >> wrote: >>> I like the new proposal better. Yet, there's one thing that bothers >>> me, which is the naming of get[Declared]Annotations(Foo.class). It's >>> way too easy to look at the API and miss the difference in behavior >>> here. I propose giving it this name: >>> get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for >>> language model's new typed method. >>> >>> Paul From pbenedict at apache.org Mon Jan 7 10:32:56 2013 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 7 Jan 2013 12:32:56 -0600 Subject: A simpler model for repeating annotations In-Reply-To: <50EAFE08.2040808@oracle.com> References: <50E4E2F7.4060704@oracle.com> <50EAFE08.2040808@oracle.com> Message-ID: I agree that "getAll" is very nebulous and does not explain why the legacy methods do not return "all". Paul On Mon, Jan 7, 2013 at 10:55 AM, michael keith wrote: > Thanks for the update, Alex. I like the direction this is going in. > > Since the get[Declared]Annotations(Class) methods are semantically different > from the others they do deserve something different in their names to > indicate it. However, given that the javadoc of the lagacy > get[Declared]Annotations() methods state simply "Returns *all* annotations > [directly] present on this element" (emphasis added) I am not sure that > adding "All" to the semantically different get[Declared]Annotations(Class) > pair is going to be a very good differentiator. Maybe "multiple" could be > used in a different way, for example: get[Declared]AnnotationsWithMultiples? > > Also, I was just wondering if the getDeclaredAnnotation(Class) method will > be considered a backfilled "new legacy" method and have similar semantics to > getAnnotation(Class), or will it look through? If it looks through then it > should be renamed as well and we might want to reconsider what the name of > the method variant is. > > -Mike > > On 02/01/2013 8:46 PM, Alex Buckley wrote: >> >> Having spent today writing out the expected behavior of core reflection >> methods, I'm sympathetic to the idea that get[Declared]Annotations(Class) >> should be more clearly distinguished. I've avoided the term "repeating" in >> API names since repetition is not really the point - the point is multiple >> applications of the same annotation type, but "multiple" has its own >> downsides since there may only be one annotation for the new methods to >> return. I'd favor something more like getAll[Declared]Annotations(Class). >> Comments welcome. >> >> Alex >> >> On 1/2/2013 7:32 AM, Paul Benedict wrote: >>> >>> BTW, I read something by Remi a few days back that was quite >>> interesting. It was from another thread. He said that correct method >>> overloading is not supposed to change behavior. Given that bit of >>> wisdom, that's why I recommend a renaming here. Behavior is changing, >>> thus a new name should be given. >>> >>> On Wed, Jan 2, 2013 at 9:22 AM, Paul Benedict >>> wrote: >>>> >>>> I like the new proposal better. Yet, there's one thing that bothers >>>> me, which is the naming of get[Declared]Annotations(Foo.class). It's >>>> way too easy to look at the API and miss the difference in behavior >>>> here. I propose giving it this name: >>>> get[Declared]RepeatingAnnotations(Foo.class) -- and do the same for >>>> language model's new typed method. >>>> >>>> Paul From alex.buckley at oracle.com Mon Jan 7 10:55:45 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 07 Jan 2013 10:55:45 -0800 Subject: A simpler model for repeating annotations In-Reply-To: <50EAFE08.2040808@oracle.com> References: <50E4E2F7.4060704@oracle.com> <50EAFE08.2040808@oracle.com> Message-ID: <50EB1A31.6080207@oracle.com> On 1/7/2013 8:55 AM, michael keith wrote: > Since the get[Declared]Annotations(Class) methods are semantically > different from the others they do deserve something different in their > names to indicate it. However, given that the javadoc of the lagacy > get[Declared]Annotations() methods state simply "Returns *all* > annotations [directly] present on this element" (emphasis added) I am > not sure that adding "All" to the semantically different > get[Declared]Annotations(Class) pair is going to be a very good > differentiator. Maybe "multiple" could be used in a different way, for > example: get[Declared]AnnotationsWithMultiples? We will in any case change the specs of legacy methods to avoid "all annotations". We will also say more about container annotation and look-through in the specs of new methods. With regard to names, an advantage of getAnnotationsWithMultiples(Class) is that it will appear after the legacy methods, which I think is better than appearing first like getAllAnnotations(Class). Stay tuned. > Also, I was just wondering if the getDeclaredAnnotation(Class) method > will be considered a backfilled "new legacy" method and have similar > semantics to getAnnotation(Class), or will it look through? The former. Per the PDF: "- Add getDeclaredAnnotation(Class). The behavior is that of getAnnotation(Class) but ignoring inherited annotations on classes. For simplicity, the added method is treated as an "SE 7 method" in the remainder of this document." Alex From pbenedict at apache.org Mon Jan 7 11:04:46 2013 From: pbenedict at apache.org (Paul Benedict) Date: Mon, 7 Jan 2013 13:04:46 -0600 Subject: A simpler model for repeating annotations In-Reply-To: <50EB1A31.6080207@oracle.com> References: <50E4E2F7.4060704@oracle.com> <50EAFE08.2040808@oracle.com> <50EB1A31.6080207@oracle.com> Message-ID: My suggestion here might be a case of over-engineering, but it's worth a shot .. even if it is shot down. While today Java is being enhanced for repeating annotations, more changes in the future might show up that will make the new methods needing a replacement too. What about an Enum for the kind of compatibility you're looking for? getWhateverNameAnnotations(Class, Enum); For example, AnnotationSourceFlags could declare { CONTAINER_ONLY, REPEATING } today with room for growth. Paul On Mon, Jan 7, 2013 at 12:55 PM, Alex Buckley wrote: > On 1/7/2013 8:55 AM, michael keith wrote: >> >> Since the get[Declared]Annotations(Class) methods are semantically >> different from the others they do deserve something different in their >> names to indicate it. However, given that the javadoc of the lagacy >> get[Declared]Annotations() methods state simply "Returns *all* >> annotations [directly] present on this element" (emphasis added) I am >> not sure that adding "All" to the semantically different >> get[Declared]Annotations(Class) pair is going to be a very good >> differentiator. Maybe "multiple" could be used in a different way, for >> example: get[Declared]AnnotationsWithMultiples? > > > We will in any case change the specs of legacy methods to avoid "all > annotations". We will also say more about container annotation and > look-through in the specs of new methods. > > With regard to names, an advantage of getAnnotationsWithMultiples(Class) is > that it will appear after the legacy methods, which I think is better than > appearing first like getAllAnnotations(Class). Stay tuned. > >> Also, I was just wondering if the getDeclaredAnnotation(Class) method >> will be considered a backfilled "new legacy" method and have similar >> semantics to getAnnotation(Class), or will it look through? > > > The former. Per the PDF: > > "- Add getDeclaredAnnotation(Class). The behavior is that of > getAnnotation(Class) but ignoring inherited annotations on classes. For > simplicity, the added method is treated as an "SE 7 method" in the remainder > of this document." > > Alex From michael.keith at oracle.com Mon Jan 7 11:27:23 2013 From: michael.keith at oracle.com (michael keith) Date: Mon, 07 Jan 2013 14:27:23 -0500 Subject: A simpler model for repeating annotations In-Reply-To: <50EB1A31.6080207@oracle.com> References: <50E4E2F7.4060704@oracle.com> <50EAFE08.2040808@oracle.com> <50EB1A31.6080207@oracle.com> Message-ID: <50EB219B.2020307@oracle.com> On 07/01/2013 1:55 PM, Alex Buckley wrote: > On 1/7/2013 8:55 AM, michael keith wrote: >> Since the get[Declared]Annotations(Class) methods are semantically >> different from the others they do deserve something different in their >> names to indicate it. However, given that the javadoc of the lagacy >> get[Declared]Annotations() methods state simply "Returns *all* >> annotations [directly] present on this element" (emphasis added) I am >> not sure that adding "All" to the semantically different >> get[Declared]Annotations(Class) pair is going to be a very good >> differentiator. Maybe "multiple" could be used in a different way, for >> example: get[Declared]AnnotationsWithMultiples? > > We will in any case change the specs of legacy methods to avoid "all > annotations". We will also say more about container annotation and > look-through in the specs of new methods. Ah, that's good. > With regard to names, an advantage of > getAnnotationsWithMultiples(Class) is that it will appear after the > legacy methods, which I think is better than appearing first like > getAllAnnotations(Class). Stay tuned. Yes, I wasn't sure if that was a plus or a minus :-) >> Also, I was just wondering if the getDeclaredAnnotation(Class) method >> will be considered a backfilled "new legacy" method and have similar >> semantics to getAnnotation(Class), or will it look through? > > The former. Per the PDF: > > "- Add getDeclaredAnnotation(Class). The behavior is that of > getAnnotation(Class) but ignoring inherited annotations on classes. > For simplicity, the added method is treated as an "SE 7 method" in the > remainder of this document." Ok. I haven't read the latest PDF yet but will do so and submit any comments ASAP. -Mike > > Alex From michael.keith at oracle.com Mon Jan 7 19:03:59 2013 From: michael.keith at oracle.com (michael keith) Date: Mon, 07 Jan 2013 22:03:59 -0500 Subject: trailing comment Message-ID: <50EB8C9F.5050608@oracle.com> Hi Alex, I went over the latest document and it all looks pretty good to me. Just one additional comment, and a minor question, of sorts. - p. 4 - Is there a use case for allowing @FooContainer to be @Documented/@Inherited when @Foo is not? In most cases seemingly arbitrary limitations are bad, but in this case I don't see a need for allowing it, and it might actually be detrimental to do so. For example, if I make a mistake as the annotation developer and during the course of development I no longer want @Foo to be @Inherited so I remove the meta-annotation from @Foo but forget to remove it from @FooContainer. When a user goes to use @Foo and annotates their UserClass with it their UserSubClass won't see it, as expected. However, if they add another @Foo then both will be wrapped in a @FooContainer and now UserSubClass will be able to see them using getAllAnnotations(Foo.class) because the container is inherited. I am just wondering if the feature was motivated by a case that someone thought would be useful, or if it was a case of trying not to impose unnecessary limitations. In general I am concerned about the maintenance issue of keeping the two annotations in sync. If they are allowed to be out of sync then the IDE won't be able to help me. Note 1: I can see the use case for different @Targets, (although I tend to believe it will be an unusual one) I'm just missing the usefulness of different @Inherited/@Documented settings. Note 2: Because container annotations is purely a mechanism to enable multiple contained annotations in EE specs, we don't actually have any meta-annotation differences between the containing and the contained annotations at all. In other words, my vision of container annotations may be biased towards them being distinctly unsophisticated. - p. 6 - The note after the first para in 9.7 states: "This rule implements the policy that an annotation may repeat at only some of the locations where the annotation may appear. See ?9.6 for more details." I don't see how the first para of 9.7 defines that behavior. Am I missing something? (It is defined in section 9.6 by the allowance of different Targets, in any case.) -Mike P.S. I'm not sure what parts, if any, of the document you are planning on lifting and using in the specs but here are some typos that I noticed as well (just in case it gets copied to a spec). - p. 9 - Feels like a typo, but the para that begins: "An annotation A is directly present on an element E if ... " should finish by saying "... contains exactly one annotation C whose type is the containing annotation type of A's type (?9.6) and whose value element contains *at least one annotation of type* A." - p. 18 - Cut/paste typo in para that begins: "Now suppose Foo is made repeatable ...". The bracketed part should be removed since it was stated above that FooContainer was inheritable (Foo may or may not be inheritable). - p. 18 - Missing closing bracket in "B.class.getAllDeclaredAnnotations(FooContainer.class = [ ]" From joe.darcy at oracle.com Mon Jan 7 19:20:31 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 07 Jan 2013 19:20:31 -0800 Subject: trailing comment In-Reply-To: <50EB8C9F.5050608@oracle.com> References: <50EB8C9F.5050608@oracle.com> Message-ID: <50EB907F.7090304@oracle.com> Hi Mike, On 1/7/2013 7:03 PM, michael keith wrote: > Hi Alex, > > I went over the latest document and it all looks pretty good to me. > Just one additional comment, and a minor question, of sorts. > > - p. 4 - Is there a use case for allowing @FooContainer to be > @Documented/@Inherited when @Foo is not? In most cases seemingly > arbitrary limitations are bad, but in this case I don't see a need for > allowing it, and it might actually be detrimental to do so. For > example, if I make a mistake as the annotation developer and during > the course of development I no longer want @Foo to be @Inherited so I > remove the meta-annotation from @Foo but forget to remove it from > @FooContainer. When a user goes to use @Foo and annotates their > UserClass with it their UserSubClass won't see it, as expected. > However, if they add another @Foo then both will be wrapped in a > @FooContainer and now UserSubClass will be able to see them using > getAllAnnotations(Foo.class) because the container is inherited. I am > just wondering if the feature was motivated by a case that someone > thought would be useful, or if it was a case of trying not to impose > unnecessary limitations. In general I am concerned about the > maintenance issue of keeping the two annotations in sync. If they are > allowed to be out of sync then the IDE won't be able to help me. > Note 1: I can see the use case for different @Targets, (although I > tend to believe it will be an unusual one) I'm just missing the > usefulness of different @Inherited/@Documented settings. > Note 2: Because container annotations is purely a mechanism to enable > multiple contained annotations in EE specs, we don't actually have any > meta-annotation differences between the containing and the contained > annotations at all. In other words, my vision of container annotations > may be biased towards them being distinctly unsophisticated. > > - p. 6 - The note after the first para in 9.7 states: > "This rule implements the policy that an annotation may repeat at > only some of the locations where the annotation may appear. See ?9.6 > for more details." > I don't see how the first para of 9.7 defines that behavior. Am I > missing something? (It is defined in section 9.6 by the allowance of > different Targets, in any case.) On the current @Target policy, in the early iterations of the proposal [1], the subset/superset relation was the opposite of what is specified now. The change was made after we examined Foo / Foos annotation type pairs in the EE specs and noticed that by design that some annotations were meant to only be selectively repeatable. Expanding such an investigation more thoroughly, it would be helpful for the existing EE annotation types to be retrofitted to use the in-progress compiler support for this pattern to verify how well the current language rules support the existing types. Thanks, -Joe [1] https://blogs.oracle.com/darcy/entry/repeating_annotations_in_the_works From ali.ebrahimi1781 at gmail.com Tue Jan 8 03:17:31 2013 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Tue, 8 Jan 2013 15:47:31 +0430 Subject: A simpler model for repeating annotations In-Reply-To: <50DDFE46.6010106@oracle.com> References: <50DDFE46.6010106@oracle.com> Message-ID: Hi Alex, I think, I'm late to list. The following is just my 2 cent suggestion to your proposal. 1) Introduce AnnotationContainer annotation in java.lang package (java se 8 ) as default container for repeating annotations: @interface AnnotationContainer{ Annotation[] value(); } (relax rules of jls 9.6.1 to include Annotation (class) type) 2) Modify Repeatable annotation: @interface Repeatable{ Class value() default AnnotationContainer.class; } with 1, 2 in mind we have one standard default container annotation for all repeating annotations that don't specify containing annotation. This allows to package all repeating annotations in one container annotation and reduce static and dynamic footprint. In other side, developer don't need to introduce one containing annotation for each repeating annotations, this also reduce number of class files and makes this feature of java 8 user friendly for developer. developer just need annotate repeating annotations with Repeatable annotation. example: @Repeatable @interface Foo { int value(); } @Repeatable @interface Bar{} @Repeatable(AliContainer.class) @interface Ali{ String value();} @interface AliContainer{ Ali[] value(); } @Foo(1) @Foo(2) @Bar @Bar @Ali("java lover") @Ali("Flying on the Clouds") class A {} in class file: @AnnotationContainer({@Foo(1), @Foo(2), @Bar, @Bar}) @AliContainer({@Ali("java lover"), at Ali("Flying on the Clouds")}) class A {} Regards, Ali Ebrahimi On Sat, Dec 29, 2012 at 12:47 AM, Alex Buckley wrote: > Feedback from Java EE architects indicates a strong preference for 100% > behavioral compatibility for legacy core reflection methods. > > Summarizing Mike Keith's comments: 1) getAnnotation(Class) must not return > one @Foo annotation if multiple @Foo annotations were present in source, > and 2) getAnnotations() must not return multiple @Foo annotations if they > present in source. > > These requirements imply keeping containment at the heart of > repeatability. Why? Assume there were no containers, and you could simply > write: > > @Repeatable @interface Foo {} > > such that @Foo @Foo on class A is compiled directly into A.class. This > scheme would impose high complexity on legacy core reflection methods. > getAnnotation(Foo.class) would have to read _all_ annotations (declared and > inherited) to detect multiple @Foo annotations then return null or throw an > exception. (Remember, returning one of the multiple annotations is > "wrong".) getAnnotations() would have similar trouble deciding what to > return if multiple @Foo annotations are found. In essence, the legacy core > reflection methods are morally incompatible with uncontained multiple > annotations. The solution is to compile multiple annotations with > containers, and have the legacy core reflection methods behave identically > to Java SE 7 (no look through). > > To support new reflective clients who understand repeating annotations, we > can keep the previously-proposed getAnnotations(Class) which looks through > containers. That is, getAnnotations(Foo.class) returns @Foo @Foo because it > a) detects that Foo.class is a repeatable annotation type with a containing > annotation type of FooContainer, then b) looks through any @FooContainer > present. > > It is clear that a repeatable annotation type must still nominate its > containing annotation type, but the reverse is no longer true. That is, the > declaration of FooContainer no longer needs to say > @ContainerFor(Foo.class). This is a direct consequence of dropping look > through for the legacy core reflection methods. Also, the difficult > question about calling getAnnotations() on a subclass - should it look > through an inherited container, or return it? - goes away, as normal > overriding policy gives good answers. > > Here's a simple model that Joe, Joel, and I are happy with: > > - @Repeatable(FooContainer.**class) on @interface Foo {} causes > @Foo @Foo in source to be containerized in the class file. > (Rename @ContainedBy to @Repeatable.) > > - The rules for a well-formed relationship between Foo and > FooContainer remain. > > - Core reflection's legacy methods return what's in the class file: > - get[Declared]Annotation(Foo.**class) returns nothing, like today. > - get[Declared]Annotations() returns @FooContainer, like today. > > - Core reflection's new typed methods look through containers: > - get[Declared]Annotations(Foo.**class) returns @Foo @Foo. > > - An annotation writer may manually rewrite @FooContainer(...) as > @Foo @Foo, and it will be containerized with perfect compatibility. > > - Language model's legacy methods follow core reflection: > - Element.getAnnotation(Foo.**class) returns nothing, like today. > - Element[s].get[All]**AnnotationMirrors() returns @FooContainer, like > today > > - Language model's new typed method looks through: > - Element.getAnnotations(Foo.**class) returns @Foo @Foo. > - We may add Element.getAnnotationMirrors(**TypeElement) in future. > > I think the reduced semantic burden for an annotation type owner (no more > @ContainedFor) and the stronger compatibility story for an annotation > reader (no look through for legacy methods) are real improvements. We will > specify and implement the model over the next month. > > Alex > From alex.buckley at oracle.com Tue Jan 8 10:54:47 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 08 Jan 2013 10:54:47 -0800 Subject: A simpler model for repeating annotations In-Reply-To: References: <50DDFE46.6010106@oracle.com> Message-ID: <50EC6B77.10803@oracle.com> Sharing a single containing annotation type between multiple repeating annotation types is not unreasonable. However, it fundamentally relies on annotation subtyping, which was not in scope for JEP 120. Alex On 1/8/2013 3:17 AM, Ali Ebrahimi wrote: > Hi Alex, > I think, I'm late to list. > The following is just my 2 cent suggestion to your proposal. > > 1) Introduce AnnotationContainer annotation in java.lang package (java > se 8 ) as default container for repeating annotations: > > @interface AnnotationContainer{ Annotation[] value(); } > (relax rules of jls 9.6.1 to include Annotation (class) type) > > 2) Modify Repeatable annotation: > @interface Repeatable{ Class value() default > AnnotationContainer.class; } > > with 1, 2 in mind we have one standard default container annotation for > all repeating annotations that don't specify containing annotation. This > allows to package all repeating annotations in one container annotation > and reduce static and dynamic footprint. In other side, developer don't > need to introduce one containing annotation for each repeating > annotations, this also reduce number of class files and makes this > feature of java 8 user friendly for developer. developer just need > annotate repeating annotations with Repeatable annotation. > > example: > > @Repeatable > @interface Foo { int value(); } > > @Repeatable > @interface Bar{} > > @Repeatable(AliContainer.class) > @interface Ali{ String value();} > > @interface AliContainer{ Ali[] value(); } > > > @Foo(1) @Foo(2) @Bar @Bar @Ali("java lover") @Ali("Flying on the Clouds") > class A {} > > in class file: > > @AnnotationContainer({@Foo(1), @Foo(2), @Bar, @Bar}) > @AliContainer({@Ali("java lover"), at Ali("Flying on the Clouds")}) > class A {} > > > Regards, > Ali Ebrahimi From ali.ebrahimi1781 at gmail.com Tue Jan 8 13:43:01 2013 From: ali.ebrahimi1781 at gmail.com (Ali Ebrahimi) Date: Wed, 9 Jan 2013 02:13:01 +0430 Subject: A simpler model for repeating annotations In-Reply-To: <50EC6B77.10803@oracle.com> References: <50DDFE46.6010106@oracle.com> <50EC6B77.10803@oracle.com> Message-ID: Hi, you mean this changes is not in scope of java 8. can we make current proposal forward compatible for such changes in future? Ali On Tue, Jan 8, 2013 at 11:24 PM, Alex Buckley wrote: > Sharing a single containing annotation type between multiple repeating > annotation types is not unreasonable. However, it fundamentally relies on > annotation subtyping, which was not in scope for JEP 120. > > Alex > > > On 1/8/2013 3:17 AM, Ali Ebrahimi wrote: > >> Hi Alex, >> I think, I'm late to list. >> The following is just my 2 cent suggestion to your proposal. >> >> 1) Introduce AnnotationContainer annotation in java.lang package (java >> se 8 ) as default container for repeating annotations: >> >> @interface AnnotationContainer{ Annotation[] value(); } >> (relax rules of jls 9.6.1 to include Annotation (class) type) >> >> 2) Modify Repeatable annotation: >> @interface Repeatable{ Class value() default >> AnnotationContainer.class; } >> >> with 1, 2 in mind we have one standard default container annotation for >> all repeating annotations that don't specify containing annotation. This >> allows to package all repeating annotations in one container annotation >> and reduce static and dynamic footprint. In other side, developer don't >> need to introduce one containing annotation for each repeating >> annotations, this also reduce number of class files and makes this >> feature of java 8 user friendly for developer. developer just need >> annotate repeating annotations with Repeatable annotation. >> >> example: >> >> @Repeatable >> @interface Foo { int value(); } >> >> @Repeatable >> @interface Bar{} >> >> @Repeatable(AliContainer.**class) >> @interface Ali{ String value();} >> >> @interface AliContainer{ Ali[] value(); } >> >> >> @Foo(1) @Foo(2) @Bar @Bar @Ali("java lover") @Ali("Flying on the Clouds") >> class A {} >> >> in class file: >> >> @AnnotationContainer({@Foo(1), @Foo(2), @Bar, @Bar}) >> @AliContainer({@Ali("java lover"), at Ali("Flying on the Clouds")}) >> class A {} >> >> >> Regards, >> Ali Ebrahimi >> > From alex.buckley at oracle.com Tue Jan 8 13:45:54 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 08 Jan 2013 13:45:54 -0800 Subject: A simpler model for repeating annotations In-Reply-To: References: <50DDFE46.6010106@oracle.com> <50EC6B77.10803@oracle.com> Message-ID: <50EC9392.5020801@oracle.com> It would be possible to add a default to Repeatable's value element and to introduce AnnotationContainer, sure. Alex On 1/8/2013 1:43 PM, Ali Ebrahimi wrote: > Hi, > you mean this changes is not in scope of java 8. can we make current > proposal forward compatible for such changes in future? > > Ali > > On Tue, Jan 8, 2013 at 11:24 PM, Alex Buckley > wrote: > > Sharing a single containing annotation type between multiple > repeating annotation types is not unreasonable. However, it > fundamentally relies on annotation subtyping, which was not in scope > for JEP 120. > > Alex > > > On 1/8/2013 3:17 AM, Ali Ebrahimi wrote: > > Hi Alex, > I think, I'm late to list. > The following is just my 2 cent suggestion to your proposal. > > 1) Introduce AnnotationContainer annotation in java.lang package > (java > se 8 ) as default container for repeating annotations: > > @interface AnnotationContainer{ Annotation[] value(); } > (relax rules of jls 9.6.1 to include Annotation (class) type) > > 2) Modify Repeatable annotation: > @interface Repeatable{ Class value() default > AnnotationContainer.class; } > > with 1, 2 in mind we have one standard default container > annotation for > all repeating annotations that don't specify containing > annotation. This > allows to package all repeating annotations in one container > annotation > and reduce static and dynamic footprint. In other side, > developer don't > need to introduce one containing annotation for each repeating > annotations, this also reduce number of class files and makes this > feature of java 8 user friendly for developer. developer just need > annotate repeating annotations with Repeatable annotation. > > example: > > @Repeatable > @interface Foo { int value(); } > > @Repeatable > @interface Bar{} > > @Repeatable(AliContainer.__class) > @interface Ali{ String value();} > > @interface AliContainer{ Ali[] value(); } > > > @Foo(1) @Foo(2) @Bar @Bar @Ali("java lover") @Ali("Flying on the > Clouds") > class A {} > > in class file: > > @AnnotationContainer({@Foo(1), @Foo(2), @Bar, @Bar}) > @AliContainer({@Ali("java lover"), at Ali("Flying on the Clouds")}) > class A {} > > > Regards, > Ali Ebrahimi > > From alex.buckley at oracle.com Tue Jan 8 17:27:01 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 08 Jan 2013 17:27:01 -0800 Subject: trailing comment In-Reply-To: <50EB8C9F.5050608@oracle.com> References: <50EB8C9F.5050608@oracle.com> Message-ID: <50ECC765.30504@oracle.com> Hi Mike, On 1/7/2013 7:03 PM, michael keith wrote: > - p. 4 - Is there a use case for allowing @FooContainer to be > @Documented/@Inherited when @Foo is not? In most cases seemingly > arbitrary limitations are bad, but in this case I don't see a need for > allowing it, and it might actually be detrimental to do so. For example, > if I make a mistake as the annotation developer and during the course of > development I no longer want @Foo to be @Inherited so I remove the > meta-annotation from @Foo but forget to remove it from @FooContainer. > When a user goes to use @Foo and annotates their UserClass with it their > UserSubClass won't see it, as expected. However, if they add another > @Foo then both will be wrapped in a @FooContainer and now UserSubClass > will be able to see them using getAllAnnotations(Foo.class) because the > container is inherited. I am just wondering if the feature was motivated > by a case that someone thought would be useful, or if it was a case of > trying not to impose unnecessary limitations. In general I am concerned > about the maintenance issue of keeping the two annotations in sync. If > they are allowed to be out of sync then the IDE won't be able to help me. Simplicity a.k.a. "both are @Inherited, or neither is" is good, but unnatural because there's no solid link from a containing annotation type to a repeatable annotation type. Consider these types: @Inherited @Repeatable(FooContainer.class) @interface Foo {} @Inherited @interface FooContainer { Foo[] value; } @Inherited @interface RandomContainer { Foo[] value; } When compiling Foo, you can't fail to notice @Repeatable, so it's reasonable to load up the named FooContainer and enforce "Foo-is- at Inherited --> FooContainer-is- at Inherited". When compiling FooContainer and RandomContainer, you don't check anything about Foo. The presence of Foo in a return type is not significant enough for a compiler to load Foo and ponder a two-way relationship. It would be a wasted effort for RandomContainer, a perfectly legal type which has nothing to do with repeatability. For FooContainer, the compiler would be happy that it and Foo are @Inherited, but that's not authoritative as I can swap in a non- at Inherited FooContainer.class at runtime. (That's why core reflection has the AnnotationFormatError check on page 10.) In summary, I think the compiler should not be expected to "save" an annotation type owner who removes @Inherited from Foo but leaves it on FooContainer. > - p. 6 - The note after the first para in 9.7 states: > "This rule implements the policy that an annotation may repeat at > only some of the locations where the annotation may appear. See ?9.6 for > more details." > I don't see how the first para of 9.7 defines that behavior. Am I > missing something? (It is defined in section 9.6 by the allowance of > different Targets, in any case.) We have a policy that an annotation may repeat at only some of the locations where the annotation may appear. This is encoded in 9.6's rules about targets, but it's not enforced until someone actually writes @Foo @Foo at a given location - then 9.7 comes into play by requiring the containing type to be legal there. The reason I also require the repeatable type to be legal there is because I plan in JLS8 to centralize rules about annotation legality which are scattered throughout JLS7. > - p. 9 - Feels like a typo, but the para that begins: "An annotation A > is directly present on an element E if ... " should finish by saying > "... contains exactly one annotation C whose type is the containing > annotation type of A's type (?9.6) and whose value element contains *at > least one annotation of type* A." That would allow @A(1) to be directly present on an element if there's a container annotation with value={@A(2)}. > - p. 18 - Cut/paste typo in para that begins: "Now suppose Foo is made > repeatable ...". The bracketed part should be removed since it was > stated above that FooContainer was inheritable (Foo may or may not be > inheritable). Thanks, corrected. > - p. 18 - Missing closing bracket in > "B.class.getAllDeclaredAnnotations(FooContainer.class = [ ]" Thanks, corrected. Alex From michael.keith at oracle.com Wed Jan 9 18:12:24 2013 From: michael.keith at oracle.com (michael keith) Date: Wed, 09 Jan 2013 21:12:24 -0500 Subject: trailing comment In-Reply-To: <50ECC765.30504@oracle.com> References: <50EB8C9F.5050608@oracle.com> <50ECC765.30504@oracle.com> Message-ID: <50EE2388.9080009@oracle.com> On 08/01/2013 8:27 PM, Alex Buckley wrote: > Hi Mike, > > On 1/7/2013 7:03 PM, michael keith wrote: >> - p. 4 - Is there a use case for allowing @FooContainer to be >> @Documented/@Inherited when @Foo is not? In most cases seemingly >> arbitrary limitations are bad, but in this case I don't see a need for >> allowing it, and it might actually be detrimental to do so. For example, >> if I make a mistake as the annotation developer and during the course of >> development I no longer want @Foo to be @Inherited so I remove the >> meta-annotation from @Foo but forget to remove it from @FooContainer. >> When a user goes to use @Foo and annotates their UserClass with it their >> UserSubClass won't see it, as expected. However, if they add another >> @Foo then both will be wrapped in a @FooContainer and now UserSubClass >> will be able to see them using getAllAnnotations(Foo.class) because the >> container is inherited. I am just wondering if the feature was motivated >> by a case that someone thought would be useful, or if it was a case of >> trying not to impose unnecessary limitations. In general I am concerned >> about the maintenance issue of keeping the two annotations in sync. If >> they are allowed to be out of sync then the IDE won't be able to help >> me. > > Simplicity a.k.a. "both are @Inherited, or neither is" is good, but > unnatural because there's no solid link from a containing annotation > type to a repeatable annotation type. Consider these types: > > @Inherited > @Repeatable(FooContainer.class) > @interface Foo {} > > @Inherited > @interface FooContainer { Foo[] value; } > > @Inherited > @interface RandomContainer { Foo[] value; } > > When compiling Foo, you can't fail to notice @Repeatable, so it's > reasonable to load up the named FooContainer and enforce > "Foo-is- at Inherited --> FooContainer-is- at Inherited". > > When compiling FooContainer and RandomContainer, you don't check > anything about Foo. The presence of Foo in a return type is not > significant enough for a compiler to load Foo and ponder a two-way > relationship. It would be a wasted effort for RandomContainer, a > perfectly legal type which has nothing to do with repeatability. For > FooContainer, the compiler would be happy that it and Foo are > @Inherited, but that's not authoritative as I can swap in a > non- at Inherited FooContainer.class at runtime. (That's why core > reflection has the AnnotationFormatError check on page 10.) > > In summary, I think the compiler should not be expected to "save" an > annotation type owner who removes @Inherited from Foo but leaves it on > FooContainer. I'm not convinced the compiler needs to verify both directions; I think it only needs to verify Foo. Foo is the annotation of interest, the one that will get modified during development. FooContainer is the uninteresting "support annotation" needed for repeatability and will likely be completely ignored once created. The only way for it to be "out of sync" with Foo is if somebody goes back and modifies FooContainer after having compiled Foo. In that unlikely case it is no different than if somebody removes a method from a class and recompiles the class, even though another class may be invoking the removed method. Either the IDE "saves" or figures out the referencer and an error shows up on the referencing class, or an exception occurs at runtime. In our annotation case, the IDE could do the same, i.e. remember the annotation/container pairs, or the AnnotationFormatError will be eagerly thrown when Foo is first loaded. That makes sense to me, and seems a more reasonable behavior than the incorrect and unexpected outcome in the scenario I described earlier. In any case, it's not a showstopper issue, I just can't think of a good use case for differing @Inherited specs (can you?) but I do see some reasons for not allowing it. >> - p. 6 - The note after the first para in 9.7 states: >> "This rule implements the policy that an annotation may repeat at >> only some of the locations where the annotation may appear. See ?9.6 for >> more details." >> I don't see how the first para of 9.7 defines that behavior. Am I >> missing something? (It is defined in section 9.6 by the allowance of >> different Targets, in any case.) > > We have a policy that an annotation may repeat at only some of the > locations where the annotation may appear. This is encoded in 9.6's > rules about targets, but it's not enforced until someone actually > writes @Foo @Foo at a given location - then 9.7 comes into play by > requiring the containing type to be legal there. > > The reason I also require the repeatable type to be legal there is > because I plan in JLS8 to centralize rules about annotation legality > which are scattered throughout JLS7. Ok, thanks. Following the train of thought that led you to include that statement was the key. >> - p. 9 - Feels like a typo, but the para that begins: "An annotation A >> is directly present on an element E if ... " should finish by saying >> "... contains exactly one annotation C whose type is the containing >> annotation type of A's type (?9.6) and whose value element contains *at >> least one annotation of type* A." > > That would allow @A(1) to be directly present on an element if there's > a container annotation with value={@A(2)}. Sorry, yes, I had a brain fart on the first phrase. >> - p. 18 - Cut/paste typo in para that begins: "Now suppose Foo is made >> repeatable ...". The bracketed part should be removed since it was >> stated above that FooContainer was inheritable (Foo may or may not be >> inheritable). > > Thanks, corrected. > >> - p. 18 - Missing closing bracket in >> "B.class.getAllDeclaredAnnotations(FooContainer.class = [ ]" > > Thanks, corrected. > > Alex From michael.keith at oracle.com Thu Jan 10 10:10:22 2013 From: michael.keith at oracle.com (michael keith) Date: Thu, 10 Jan 2013 13:10:22 -0500 Subject: trailing comment In-Reply-To: <50EE2388.9080009@oracle.com> References: <50EB8C9F.5050608@oracle.com> <50ECC765.30504@oracle.com> <50EE2388.9080009@oracle.com> Message-ID: <50EF040E.5090500@oracle.com> On 09/01/2013 9:12 PM, michael keith wrote: > On 08/01/2013 8:27 PM, Alex Buckley wrote: >> Hi Mike, >> >> On 1/7/2013 7:03 PM, michael keith wrote: >>> - p. 4 - Is there a use case for allowing @FooContainer to be >>> @Documented/@Inherited when @Foo is not? In most cases seemingly >>> arbitrary limitations are bad, but in this case I don't see a need for >>> allowing it, and it might actually be detrimental to do so. For >>> example, >>> if I make a mistake as the annotation developer and during the >>> course of >>> development I no longer want @Foo to be @Inherited so I remove the >>> meta-annotation from @Foo but forget to remove it from @FooContainer. >>> When a user goes to use @Foo and annotates their UserClass with it >>> their >>> UserSubClass won't see it, as expected. However, if they add another >>> @Foo then both will be wrapped in a @FooContainer and now UserSubClass >>> will be able to see them using getAllAnnotations(Foo.class) because the >>> container is inherited. I am just wondering if the feature was >>> motivated >>> by a case that someone thought would be useful, or if it was a case of >>> trying not to impose unnecessary limitations. In general I am concerned >>> about the maintenance issue of keeping the two annotations in sync. If >>> they are allowed to be out of sync then the IDE won't be able to >>> help me. >> >> Simplicity a.k.a. "both are @Inherited, or neither is" is good, but >> unnatural because there's no solid link from a containing annotation >> type to a repeatable annotation type. Consider these types: >> >> @Inherited >> @Repeatable(FooContainer.class) >> @interface Foo {} >> >> @Inherited >> @interface FooContainer { Foo[] value; } >> >> @Inherited >> @interface RandomContainer { Foo[] value; } >> >> When compiling Foo, you can't fail to notice @Repeatable, so it's >> reasonable to load up the named FooContainer and enforce >> "Foo-is- at Inherited --> FooContainer-is- at Inherited". >> >> When compiling FooContainer and RandomContainer, you don't check >> anything about Foo. The presence of Foo in a return type is not >> significant enough for a compiler to load Foo and ponder a two-way >> relationship. It would be a wasted effort for RandomContainer, a >> perfectly legal type which has nothing to do with repeatability. For >> FooContainer, the compiler would be happy that it and Foo are >> @Inherited, but that's not authoritative as I can swap in a >> non- at Inherited FooContainer.class at runtime. (That's why core >> reflection has the AnnotationFormatError check on page 10.) >> >> In summary, I think the compiler should not be expected to "save" an >> annotation type owner who removes @Inherited from Foo but leaves it >> on FooContainer. > > I'm not convinced the compiler needs to verify both directions; I > think it only needs to verify Foo. Foo is the annotation of interest, > the one that will get modified during development. FooContainer is the > uninteresting "support annotation" needed for repeatability and will > likely be completely ignored once created. The only way for it to be > "out of sync" with Foo is if somebody goes back and modifies > FooContainer after having compiled Foo. In that unlikely case it is no > different than if somebody removes a method from a class and > recompiles the class, even though another class may be invoking the > removed method. Either the IDE "saves" or figures out the referencer > and an error shows up on the referencing class, or an exception occurs > at runtime. In our annotation case, the IDE could do the same, i.e. > remember the annotation/container pairs, or the AnnotationFormatError > will be eagerly thrown when Foo is first loaded. That makes sense to > me, and seems a more reasonable behavior than the incorrect and > unexpected outcome in the scenario I described earlier. I should also have mentioned that the current restrictions aready result in the load-time exception (but no compile-time exception) if a container type is modified to *not* be @Inherited, when Foo is. Because there is no link back to Foo, both that case plus the case of a containing annotation type having a lesser Retention setting than the type it contains, will not be caught when compiling the containing type. They will only be noticed when the contained annotation type is loaded and validated for well-formed repeatability. > In any case, it's not a showstopper issue, I just can't think of a > good use case for differing @Inherited specs (can you?) but I do see > some reasons for not allowing it. >>> - p. 6 - The note after the first para in 9.7 states: >>> "This rule implements the policy that an annotation may repeat at >>> only some of the locations where the annotation may appear. See ?9.6 >>> for >>> more details." >>> I don't see how the first para of 9.7 defines that behavior. Am I >>> missing something? (It is defined in section 9.6 by the allowance of >>> different Targets, in any case.) >> >> We have a policy that an annotation may repeat at only some of the >> locations where the annotation may appear. This is encoded in 9.6's >> rules about targets, but it's not enforced until someone actually >> writes @Foo @Foo at a given location - then 9.7 comes into play by >> requiring the containing type to be legal there. >> >> The reason I also require the repeatable type to be legal there is >> because I plan in JLS8 to centralize rules about annotation legality >> which are scattered throughout JLS7. > > Ok, thanks. Following the train of thought that led you to include > that statement was the key. > >>> - p. 9 - Feels like a typo, but the para that begins: "An annotation A >>> is directly present on an element E if ... " should finish by saying >>> "... contains exactly one annotation C whose type is the containing >>> annotation type of A's type (?9.6) and whose value element contains *at >>> least one annotation of type* A." >> >> That would allow @A(1) to be directly present on an element if >> there's a container annotation with value={@A(2)}. > > Sorry, yes, I had a brain fart on the first phrase. > >>> - p. 18 - Cut/paste typo in para that begins: "Now suppose Foo is made >>> repeatable ...". The bracketed part should be removed since it was >>> stated above that FooContainer was inheritable (Foo may or may not be >>> inheritable). >> >> Thanks, corrected. >> >>> - p. 18 - Missing closing bracket in >>> "B.class.getAllDeclaredAnnotations(FooContainer.class = [ ]" >> >> Thanks, corrected. >> >> Alex From alex.buckley at oracle.com Thu Jan 10 13:01:10 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 10 Jan 2013 13:01:10 -0800 Subject: trailing comment In-Reply-To: <50EF040E.5090500@oracle.com> References: <50EB8C9F.5050608@oracle.com> <50ECC765.30504@oracle.com> <50EE2388.9080009@oracle.com> <50EF040E.5090500@oracle.com> Message-ID: <50EF2C16.4070500@oracle.com> On 1/10/2013 10:10 AM, michael keith wrote: > On 09/01/2013 9:12 PM, michael keith wrote: >> On 08/01/2013 8:27 PM, Alex Buckley wrote: >>> Hi Mike, >>> >>> On 1/7/2013 7:03 PM, michael keith wrote: >>>> - p. 4 - Is there a use case for allowing @FooContainer to be >>>> @Documented/@Inherited when @Foo is not? In most cases seemingly >>>> arbitrary limitations are bad, but in this case I don't see a need for >>>> allowing it, and it might actually be detrimental to do so. For >>>> example, >>>> if I make a mistake as the annotation developer and during the >>>> course of >>>> development I no longer want @Foo to be @Inherited so I remove the >>>> meta-annotation from @Foo but forget to remove it from @FooContainer. >>>> When a user goes to use @Foo and annotates their UserClass with it >>>> their >>>> UserSubClass won't see it, as expected. However, if they add another >>>> @Foo then both will be wrapped in a @FooContainer and now UserSubClass >>>> will be able to see them using getAllAnnotations(Foo.class) because the >>>> container is inherited. I am just wondering if the feature was >>>> motivated >>>> by a case that someone thought would be useful, or if it was a case of >>>> trying not to impose unnecessary limitations. In general I am concerned >>>> about the maintenance issue of keeping the two annotations in sync. If >>>> they are allowed to be out of sync then the IDE won't be able to >>>> help me. >>> >>> Simplicity a.k.a. "both are @Inherited, or neither is" is good, but >>> unnatural because there's no solid link from a containing annotation >>> type to a repeatable annotation type. Consider these types: >>> >>> @Inherited >>> @Repeatable(FooContainer.class) >>> @interface Foo {} >>> >>> @Inherited >>> @interface FooContainer { Foo[] value; } >>> >>> @Inherited >>> @interface RandomContainer { Foo[] value; } >>> >>> When compiling Foo, you can't fail to notice @Repeatable, so it's >>> reasonable to load up the named FooContainer and enforce >>> "Foo-is- at Inherited --> FooContainer-is- at Inherited". >>> >>> When compiling FooContainer and RandomContainer, you don't check >>> anything about Foo. The presence of Foo in a return type is not >>> significant enough for a compiler to load Foo and ponder a two-way >>> relationship. It would be a wasted effort for RandomContainer, a >>> perfectly legal type which has nothing to do with repeatability. For >>> FooContainer, the compiler would be happy that it and Foo are >>> @Inherited, but that's not authoritative as I can swap in a >>> non- at Inherited FooContainer.class at runtime. (That's why core >>> reflection has the AnnotationFormatError check on page 10.) >>> >>> In summary, I think the compiler should not be expected to "save" an >>> annotation type owner who removes @Inherited from Foo but leaves it >>> on FooContainer. >> >> I'm not convinced the compiler needs to verify both directions; I >> think it only needs to verify Foo. Foo is the annotation of interest, >> the one that will get modified during development. FooContainer is the >> uninteresting "support annotation" needed for repeatability and will >> likely be completely ignored once created. The only way for it to be >> "out of sync" with Foo is if somebody goes back and modifies >> FooContainer after having compiled Foo. In that unlikely case it is no >> different than if somebody removes a method from a class and >> recompiles the class, even though another class may be invoking the >> removed method. Either the IDE "saves" or figures out the referencer >> and an error shows up on the referencing class, or an exception occurs >> at runtime. In our annotation case, the IDE could do the same, i.e. >> remember the annotation/container pairs, or the AnnotationFormatError >> will be eagerly thrown when Foo is first loaded. That makes sense to >> me, and seems a more reasonable behavior than the incorrect and >> unexpected outcome in the scenario I described earlier. > > I should also have mentioned that the current restrictions aready result > in the load-time exception (but no compile-time exception) if a > container type is modified to *not* be @Inherited, when Foo is. Because > there is no link back to Foo, both that case plus the case of a > containing annotation type having a lesser Retention setting than the > type it contains, will not be caught when compiling the containing type. > They will only be noticed when the contained annotation type is loaded > and validated for well-formed repeatability. I agree with everything you say above. What I should have said more clearly is this: there is no "use case" per se for allowing FooContainer to be @Documented/@Inherited when Foo is not. It's just that we can't easily detect it at compile-time, due to separate compilation. It slips by as something you can do, but probably shouldn't. There are an infinite number of programs in that vein "allowed" by the JLS. Since the scenario is ultimately harmless, we don't need to prevent it at runtime either. In the dual case - Foo is @Documented/@Inherited but FooContainer isn't - there is clearly badness. Since we can't detect it at compile-time, there is a runtime check. Alex From alex.buckley at oracle.com Thu Jan 10 15:59:10 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 10 Jan 2013 15:59:10 -0800 Subject: trailing comment In-Reply-To: <50ECC765.30504@oracle.com> References: <50EB8C9F.5050608@oracle.com> <50ECC765.30504@oracle.com> Message-ID: <50EF55CE.4020703@oracle.com> On 1/8/2013 5:27 PM, Alex Buckley wrote: >> - p. 18 - Cut/paste typo in para that begins: "Now suppose Foo is made >> repeatable ...". The bracketed part should be removed since it was >> stated above that FooContainer was inheritable (Foo may or may not be >> inheritable). > > Thanks, corrected. > >> - p. 18 - Missing closing bracket in >> "B.class.getAllDeclaredAnnotations(FooContainer.class = [ ]" > > Thanks, corrected. I have updated the spec at http://cr.openjdk.java.net/~abuckley/8misc.pdf with these corrections, and also clarified that a method parameter in the new class file attribute may have no name. Alex From pbenedict at apache.org Tue Jan 22 09:41:47 2013 From: pbenedict at apache.org (Paul Benedict) Date: Tue, 22 Jan 2013 11:41:47 -0600 Subject: ContainedBy/ContainerFor on chopping block? Message-ID: With jdk8b73, @Repeatable has now been promoted into the official build. I assume this means the other 2 annotations will be removed? I think they were got squelched in the last spec revision. From joe.darcy at oracle.com Tue Jan 22 09:48:23 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 22 Jan 2013 09:48:23 -0800 Subject: ContainedBy/ContainerFor on chopping block? In-Reply-To: References: Message-ID: <50FED0E7.8000607@oracle.com> On 1/22/2013 9:41 AM, Paul Benedict wrote: > With jdk8b73, @Repeatable has now been promoted into the official build. I > assume this means the other 2 annotations will be removed? I think they > were got squelched in the last spec revision. The ContainedBy and ContainerFor types will be removed once core reflection is updated to look at Repeatable instead: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8005832 -Joe From eric.mccorkle at oracle.com Thu Jan 24 11:58:53 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 24 Jan 2013 14:58:53 -0500 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <510191C7.3020006@oracle.com> References: <51018C89.6040605@oracle.com> <51018E2D.8080405@oracle.com> <510191C7.3020006@oracle.com> Message-ID: <5101927D.60801@oracle.com> Discussion moved from core-libs-dev to enhanced-metadata-spec-discuss On 01/24/13 14:55, Eric McCorkle wrote: > On 01/24/13 14:40, Jonathan Gibbons wrote: >> On 01/24/2013 11:33 AM, Eric McCorkle wrote: >>> The current version of the spec for parameter reflection, found here: >>> >>> http://cr.openjdk.java.net/~abuckley/8misc.pdf >>> >>> states that if a parameter has no name, then the reflection API should >>> synthesize a name of the form "argN", where N is the index of the >>> parameter. It also states that if a MethodParameters attribute has a >>> name index of 0, then it indicates a parameter with no name. >>> >>> The question I have is, what if a MethodParameters attribute indicates a >>> name of "" (meaning, the empty string)? Does this count as a valid >>> name, or should it be treated as a parameter with no name? >>> >>> >>> It is probably also worth thinking about invalid parameter names, for >>> example "10", "_", "+", " ", other whitespace characters, and so on. >> >> What about name clashes, such as if I choose to name my args "arg3, >> arg2, arg1, arg0" >> >> Are valid parameter names JVMS identifiers or JLS identifiers? >> > > It bears mention that Java may not be the only language using this > feature. Lisp (clojure) comes to mind, where names frequently have "-" > in them. There might also be languages out there where "0" is a valid > identifier. > > Also, one could imagine a language with nameless parameters in the style > of C++, or _ in the style of SML. But I really can't see a compelling > case why "" would be distinct from being unnamed. From alex.buckley at oracle.com Thu Jan 24 12:35:49 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 12:35:49 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <51018C89.6040605@oracle.com> References: <51018C89.6040605@oracle.com> Message-ID: <51019B25.5040309@oracle.com> // See new recipients of this mail. // No re-posting of content between lists with different licenses, please. On 1/24/2013 11:33 AM, Eric McCorkle wrote: > The current version of the spec for parameter reflection, found here: > > http://cr.openjdk.java.net/~abuckley/8misc.pdf > > states that if a parameter has no name, then the reflection API should > synthesize a name of the form "argN", where N is the index of the > parameter. It also states that if a MethodParameters attribute has a > name index of 0, then it indicates a parameter with no name. > > The question I have is, what if a MethodParameters attribute indicates a > name of "" (meaning, the empty string)? Does this count as a valid > name, or should it be treated as a parameter with no name? For simplicity, I would be OK with saying that the name of a method parameter is an "unqualified name" per JVMS 4.2.2. That bans . ; [ / and allows everything else. For compilers targeting the ClassFile format, this is a reasonable trade-off between freedom and convention. I would also say that an unqualified name (regardless of its role as a field name, parameter name, etc) must consist of at least one ASCII character in addition to not containing certain characters. That is, I'm happy to declare "" out of bounds for MethodParameters to avoid confusion with a 0 index (which I think remains a useful escape hatch for compilers). How does all that sound? Alex From eric.mccorkle at oracle.com Thu Jan 24 12:47:08 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 24 Jan 2013 15:47:08 -0500 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <51019B25.5040309@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> Message-ID: <51019DCC.4010802@oracle.com> On 01/24/13 15:35, Alex Buckley wrote: > // See new recipients of this mail. > > // No re-posting of content between lists with different licenses, please. > > On 1/24/2013 11:33 AM, Eric McCorkle wrote: >> The current version of the spec for parameter reflection, found here: >> >> http://cr.openjdk.java.net/~abuckley/8misc.pdf >> >> states that if a parameter has no name, then the reflection API should >> synthesize a name of the form "argN", where N is the index of the >> parameter. It also states that if a MethodParameters attribute has a >> name index of 0, then it indicates a parameter with no name. >> >> The question I have is, what if a MethodParameters attribute indicates a >> name of "" (meaning, the empty string)? Does this count as a valid >> name, or should it be treated as a parameter with no name? > > For simplicity, I would be OK with saying that the name of a method > parameter is an "unqualified name" per JVMS 4.2.2. That bans . ; [ / and > allows everything else. For compilers targeting the ClassFile format, > this is a reasonable trade-off between freedom and convention. > > I would also say that an unqualified name (regardless of its role as a > field name, parameter name, etc) must consist of at least one ASCII > character in addition to not containing certain characters. That is, I'm > happy to declare "" out of bounds for MethodParameters to avoid > confusion with a 0 index (which I think remains a useful escape hatch > for compilers). > > How does all that sound? > That sounds fine to me. From alex.buckley at oracle.com Thu Jan 24 13:05:53 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 13:05:53 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <51019DCC.4010802@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <51019DCC.4010802@oracle.com> Message-ID: <5101A231.5070505@oracle.com> JVM implementers on this list should note the explicit new constraint that an unqualified name (JVMS 4.2.2) must be non-zero-length. I would not like it to come as a surprise when JVMS8 appears in the Proposed Final Draft of JSR 337. Alex On 1/24/2013 12:47 PM, Eric McCorkle wrote: > On 01/24/13 15:35, Alex Buckley wrote: >> // See new recipients of this mail. >> >> // No re-posting of content between lists with different licenses, please. >> >> On 1/24/2013 11:33 AM, Eric McCorkle wrote: >>> The current version of the spec for parameter reflection, found here: >>> >>> http://cr.openjdk.java.net/~abuckley/8misc.pdf >>> >>> states that if a parameter has no name, then the reflection API should >>> synthesize a name of the form "argN", where N is the index of the >>> parameter. It also states that if a MethodParameters attribute has a >>> name index of 0, then it indicates a parameter with no name. >>> >>> The question I have is, what if a MethodParameters attribute indicates a >>> name of "" (meaning, the empty string)? Does this count as a valid >>> name, or should it be treated as a parameter with no name? >> >> For simplicity, I would be OK with saying that the name of a method >> parameter is an "unqualified name" per JVMS 4.2.2. That bans . ; [ / and >> allows everything else. For compilers targeting the ClassFile format, >> this is a reasonable trade-off between freedom and convention. >> >> I would also say that an unqualified name (regardless of its role as a >> field name, parameter name, etc) must consist of at least one ASCII >> character in addition to not containing certain characters. That is, I'm >> happy to declare "" out of bounds for MethodParameters to avoid >> confusion with a 0 index (which I think remains a useful escape hatch >> for compilers). >> >> How does all that sound? >> > > That sounds fine to me. From michael.keith at oracle.com Thu Jan 24 13:16:18 2013 From: michael.keith at oracle.com (michael keith) Date: Thu, 24 Jan 2013 16:16:18 -0500 Subject: some more fiddling Message-ID: <5101A4A2.7030801@oracle.com> 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. 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 :-) 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? Thanks, -Mike From peter.jensen at oracle.com Thu Jan 24 13:00:24 2013 From: peter.jensen at oracle.com (Peter Jensen) Date: Thu, 24 Jan 2013 13:00:24 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <51019B25.5040309@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> Message-ID: <5101A0E8.2050507@oracle.com> On 01/24/13 12:35, Alex Buckley wrote: > // See new recipients of this mail. > > // No re-posting of content between lists with different licenses, > please. > > On 1/24/2013 11:33 AM, Eric McCorkle wrote: >> The current version of the spec for parameter reflection, found here: >> >> http://cr.openjdk.java.net/~abuckley/8misc.pdf >> >> states that if a parameter has no name, then the reflection API should >> synthesize a name of the form "argN", where N is the index of the >> parameter. It also states that if a MethodParameters attribute has a >> name index of 0, then it indicates a parameter with no name. >> >> The question I have is, what if a MethodParameters attribute indicates a >> name of "" (meaning, the empty string)? Does this count as a valid >> name, or should it be treated as a parameter with no name? > > For simplicity, I would be OK with saying that the name of a method > parameter is an "unqualified name" per JVMS 4.2.2. That bans . ; [ / > and allows everything else. For compilers targeting the ClassFile > format, this is a reasonable trade-off between freedom and convention. > > I would also say that an unqualified name (regardless of its role as a > field name, parameter name, etc) must consist of at least one ASCII > character in addition to not containing certain characters. That is, > I'm happy to declare "" out of bounds for MethodParameters to avoid > confusion with a 0 index (which I think remains a useful escape hatch > for compilers). > > How does all that sound? The VM will not enforce any rules, I presume. The spec says it doesn't enforce the parameter_count restriction, and I presume it doesn't enforce any name restrictions (unless it already does so generally for constant pool entries?) The reflection API doesn't say how it deals with broken restrictions. For instance, - does it supplement missing arguments, as if they have no names - does it silently ignore extra names, or does it report all names present. - if you define any restrictions on the content of names, how does the API deal with broken names (e.g. does it remove none printable characters (e.g. backspace)). Note: I don't see a reason to give "" a special treatment. As far as I'm concerned, that's just one more whitespace than "\u0008". The later may actually be useful, since the toString() specification mandates a space before the parameter name:-) And why at least one ASCII character? That's not I18n friendly On the other hand, allowing any string as-is may not be safe (e.g. a bunch of control characters). > > Alex From peter.jensen at oracle.com Thu Jan 24 13:11:49 2013 From: peter.jensen at oracle.com (Peter Jensen) Date: Thu, 24 Jan 2013 13:11:49 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101A0E8.2050507@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> Message-ID: <5101A395.6050104@oracle.com> > The VM will not enforce any rules, I presume. The spec says it doesn't > enforce the parameter_count restriction, and I presume it > doesn't enforce any name restrictions (unless it already does so > generally for constant pool entries?) BTW: must the VM enforce the "at most one MethodParameters attribute" restriction. The spec doesn't say. From michael.keith at oracle.com Thu Jan 24 13:52:34 2013 From: michael.keith at oracle.com (michael keith) Date: Thu, 24 Jan 2013 16:52:34 -0500 Subject: some more fiddling In-Reply-To: <5101A4A2.7030801@oracle.com> References: <5101A4A2.7030801@oracle.com> Message-ID: <5101AD22.5040502@oracle.com> Oh, one other thing that I found is probably worth reporting as well. I thought I remembered that annotations were supposed to be returned in the order they appeared on the annotated element but I found that not to be the case in one instance. Using the test case @FooContainer({ @Foo(1), @Foo(2) }) @Foo(3) class A {} and invoking getAnnotations(Foo.class) the result was [ @Foo(3), @Foo(1), @Foo(2) ]. Calling getAnnotations() returned [ @Foo(1), @Foo(2), @Foo(3) ], which is not backwards compatible but is at least in the correct order! -Mike On 24/01/2013 4: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. 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 :-) > > 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? > > Thanks, > -Mike From alex.buckley at oracle.com Thu Jan 24 13:53:04 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 13:53:04 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101A0E8.2050507@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> Message-ID: <5101AD40.1050706@oracle.com> On 1/24/2013 1:00 PM, Peter Jensen wrote: > The VM will not enforce any rules, I presume. The spec says it doesn't > enforce the parameter_count restriction, and I presume it > doesn't enforce any name restrictions (unless it already does so > generally for constant pool entries?) Default behavior of a JVM implementation is to enforce every normative clause in the JVMS unless the JVMS says otherwise. Here's an example of a normative clause: "... MethodParameters, which may appear only, and at most once, in the attributes table of a method_info structure". Another normative clause is that parameter_name_index is either 0 or points to a CONSTANT_Utf8_info. I am aware that JVM implementers sometimes have difficulty with format checking of the "reflective" attributes (Signature, Runtime*Annotations, and now MethodParameters), but those issues should not be raised on this spec list. > The reflection API doesn't say how it deals with broken restrictions. > For instance, > - does it supplement missing arguments, as if they have no names > - does it silently ignore extra names, or does it report all names present. > - if you define any restrictions on the content of names, how does the > API deal with broken names > (e.g. does it remove none printable characters (e.g. backspace)). To be precise, if there is a mismatch between parameters_count and the number of parameters in method_info.descriptor_index (see 8misc.pdf 2.1), or if names are not well-formed parameter names, then core reflection should throw a ReflectiveOperationException. Eric, what does the Reference Implementation currently do? (Remember this is not a GPL'd list.) > Note: I don't see a reason to give "" a special treatment. As far as I'm > concerned, that's just one > more whitespace than "\u0008". The later may actually be useful, since > the toString() specification > mandates a space before the parameter name:-) > > And why at least one ASCII character? That's not I18n friendly > > On the other hand, allowing any string as-is may not be safe (e.g. a > bunch of control characters). I'm well aware of Unicode v. ASCII, but I want to keep things real simple for this Java SE 8 feature right now. Alex From alex.buckley at oracle.com Thu Jan 24 14:12:47 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 14:12:47 -0800 Subject: some more fiddling In-Reply-To: <5101A4A2.7030801@oracle.com> References: <5101A4A2.7030801@oracle.com> Message-ID: <5101B1DF.3050500@oracle.com> Core reflection isn't reverted yet so you're still getting look-through. It will be in before M7. @Repeatable + the compiler changes to understand it should appear in JDK8 b74. Alex 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. 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 :-) > > 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? > > Thanks, > -Mike From joe.darcy at oracle.com Thu Jan 24 14:14:45 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 24 Jan 2013 14:14:45 -0800 Subject: some more fiddling In-Reply-To: <5101A4A2.7030801@oracle.com> References: <5101A4A2.7030801@oracle.com> Message-ID: <5101B255.4060904@oracle.com> 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. Thanks, -Joe From eric.mccorkle at oracle.com Thu Jan 24 15:24:35 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 24 Jan 2013 18:24:35 -0500 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101AD40.1050706@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> Message-ID: <5101C2B3.3040904@oracle.com> On 01/24/13 16:53, Alex Buckley wrote: >> The reflection API doesn't say how it deals with broken restrictions. >> For instance, >> - does it supplement missing arguments, as if they have no names >> - does it silently ignore extra names, or does it report all names >> present. >> - if you define any restrictions on the content of names, how does the >> API deal with broken names >> (e.g. does it remove none printable characters (e.g. backspace)). > > To be precise, if there is a mismatch between parameters_count and the > number of parameters in method_info.descriptor_index (see 8misc.pdf > 2.1), or if names are not well-formed parameter names, then core > reflection should throw a ReflectiveOperationException. > > Eric, what does the Reference Implementation currently do? (Remember > this is not a GPL'd list.) > The reference implementation (which is under active testing and fixing) presently reports whatever is in the MethodParameters attribute, and will not throw an exception; however, this is going to change very soon. The case outlined above is one of the cases I have flagged for testing. From alex.buckley at oracle.com Thu Jan 24 16:10:30 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 16:10:30 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101C2B3.3040904@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> Message-ID: <5101CD76.2040807@oracle.com> On 1/24/2013 3:24 PM, Eric McCorkle wrote: > On 01/24/13 16:53, Alex Buckley wrote: >> To be precise, if there is a mismatch between parameters_count and the >> number of parameters in method_info.descriptor_index (see 8misc.pdf >> 2.1), or if names are not well-formed parameter names, then core >> reflection should throw a ReflectiveOperationException. >> >> Eric, what does the Reference Implementation currently do? (Remember >> this is not a GPL'd list.) > > The reference implementation (which is under active testing and fixing) > presently reports whatever is in the MethodParameters attribute, and > will not throw an exception; however, this is going to change very soon. OK. In anticipation of developments in this area, I have uploaded a new spec PDF which constrains parameter names and requires that core reflection must detect ill-formed items in MethodParameters. There is also a change to the structure of MethodParameters itself (sorry). u4 parameter_flags is now u2 access_flags. The reason for u4->u2 is that the last unused bit in a u2 access_flags - 0x8000 - is now available to denote ACC_SYNTHESIZED. (See the discussion in http://cr.openjdk.java.net/~abuckley/8misc-20130109.pdf for why 0x8000 was not available until now.) Finally, there is a clarification w.r.t. @Target for repeatable/containing annotation types. Alex From alex.buckley at oracle.com Thu Jan 24 16:12:44 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 16:12:44 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101C2B3.3040904@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> Message-ID: <5101CDFC.10905@oracle.com> On 1/24/2013 3:24 PM, Eric McCorkle wrote: > On 01/24/13 16:53, Alex Buckley wrote: >> To be precise, if there is a mismatch between parameters_count and the >> number of parameters in method_info.descriptor_index (see 8misc.pdf >> 2.1), or if names are not well-formed parameter names, then core >> reflection should throw a ReflectiveOperationException. >> >> Eric, what does the Reference Implementation currently do? (Remember >> this is not a GPL'd list.) > > The reference implementation (which is under active testing and fixing) > presently reports whatever is in the MethodParameters attribute, and > will not throw an exception; however, this is going to change very soon. OK. In anticipation of developments in this area, I have uploaded a new spec PDF which constrains parameter names and requires that core reflection must detect ill-formed items in MethodParameters. See: http://cr.openjdk.java.net/~abuckley/8misc.pdf There is also a change to the structure of MethodParameters itself (sorry). u4 parameter_flags is now u2 access_flags. The reason for u4->u2 is that the last unused bit in a u2 access_flags - 0x8000 - is now available to denote ACC_SYNTHESIZED. This is a very pleasing development. (See the discussion in the previous PDF, http://cr.openjdk.java.net/~abuckley/8misc-20130109.pdf, for why 0x8000 was not available previously.) Finally, there is a clarification w.r.t. @Target for repeatable/containing annotation types. Alex From pbenedict at apache.org Thu Jan 24 16:27:52 2013 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 24 Jan 2013 18:27:52 -0600 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101CDFC.10905@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> <5101CDFC.10905@oracle.com> Message-ID: Why wait until runtime to discover ill-formed parameter names? Wouldn't it be better to catch these at verification time? On Jan 24, 2013 6:13 PM, "Alex Buckley" wrote: > On 1/24/2013 3:24 PM, Eric McCorkle wrote: > >> On 01/24/13 16:53, Alex Buckley wrote: >> >>> To be precise, if there is a mismatch between parameters_count and the >>> number of parameters in method_info.descriptor_index (see 8misc.pdf >>> 2.1), or if names are not well-formed parameter names, then core >>> reflection should throw a ReflectiveOperationException. >>> >>> Eric, what does the Reference Implementation currently do? (Remember >>> this is not a GPL'd list.) >>> >> >> The reference implementation (which is under active testing and fixing) >> presently reports whatever is in the MethodParameters attribute, and >> will not throw an exception; however, this is going to change very soon. >> > > OK. In anticipation of developments in this area, I have uploaded a new > spec PDF which constrains parameter names and requires that core reflection > must detect ill-formed items in MethodParameters. See: > > http://cr.openjdk.java.net/~**abuckley/8misc.pdf > > There is also a change to the structure of MethodParameters itself > (sorry). u4 parameter_flags is now u2 access_flags. The reason for u4->u2 > is that the last unused bit in a u2 access_flags - 0x8000 - is now > available to denote ACC_SYNTHESIZED. This is a very pleasing development. > > (See the discussion in the previous PDF, http://cr.openjdk.java.net/~** > abuckley/8misc-20130109.pdf, > for why 0x8000 was not available previously.) > > Finally, there is a clarification w.r.t. @Target for repeatable/containing > annotation types. > > Alex > From pbenedict at apache.org Thu Jan 24 16:31:13 2013 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 24 Jan 2013 18:31:13 -0600 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> <5101CDFC.10905@oracle.com> Message-ID: Why wait until runtime to discover ill-formed parameter names? Wouldn't it be better to catch these at verification time? On Jan 24, 2013 6:13 PM, "Alex Buckley" wrote: From alex.buckley at oracle.com Thu Jan 24 16:40:28 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Jan 2013 16:40:28 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> <5101CDFC.10905@oracle.com> Message-ID: <5101D47C.5060706@oracle.com> On 1/24/2013 4:27 PM, Paul Benedict wrote: > Why wait until runtime to discover ill-formed parameter names? Wouldn't > it be better to catch these at verification time? JVM implementations typically do not perform, at class load time, exhaustive format checking of attributes which are inessential to JVM operation. (See JVMS 4.8 and 5.3.5). Verification is a term often used incorrectly; it applies to Code attributes and nothing else. (See JVMS 4.9 and 5.4.1.) Alex From joe.darcy at oracle.com Fri Jan 25 14:26:39 2013 From: joe.darcy at oracle.com (Joseph Darcy) Date: Fri, 25 Jan 2013 14:26:39 -0800 Subject: Parameter reflection: parameters with "" as their name In-Reply-To: <5101CDFC.10905@oracle.com> References: <51018C89.6040605@oracle.com> <51019B25.5040309@oracle.com> <5101A0E8.2050507@oracle.com> <5101AD40.1050706@oracle.com> <5101C2B3.3040904@oracle.com> <5101CDFC.10905@oracle.com> Message-ID: <5103069F.5000106@oracle.com> Hello, From earlier in the thread, I don't think it would be reasonable to *require* an ASCII character in a parameter name (there is no such requirement in Java source code), but I see that restriction is *not* in the current specification. Cheers, -Joe On 1/24/2013 4:12 PM, Alex Buckley wrote: > On 1/24/2013 3:24 PM, Eric McCorkle wrote: >> On 01/24/13 16:53, Alex Buckley wrote: >>> To be precise, if there is a mismatch between parameters_count and the >>> number of parameters in method_info.descriptor_index (see 8misc.pdf >>> 2.1), or if names are not well-formed parameter names, then core >>> reflection should throw a ReflectiveOperationException. >>> >>> Eric, what does the Reference Implementation currently do? (Remember >>> this is not a GPL'd list.) >> >> The reference implementation (which is under active testing and fixing) >> presently reports whatever is in the MethodParameters attribute, and >> will not throw an exception; however, this is going to change very soon. > > OK. In anticipation of developments in this area, I have uploaded a > new spec PDF which constrains parameter names and requires that core > reflection must detect ill-formed items in MethodParameters. See: > > http://cr.openjdk.java.net/~abuckley/8misc.pdf > > There is also a change to the structure of MethodParameters itself > (sorry). u4 parameter_flags is now u2 access_flags. The reason for > u4->u2 is that the last unused bit in a u2 access_flags - 0x8000 - is > now available to denote ACC_SYNTHESIZED. This is a very pleasing > development. > > (See the discussion in the previous PDF, > http://cr.openjdk.java.net/~abuckley/8misc-20130109.pdf, for why > 0x8000 was not available previously.) > > Finally, there is a clarification w.r.t. @Target for > repeatable/containing annotation types. > > Alex From alex.buckley at oracle.com Wed Jan 30 15:16:54 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 30 Jan 2013 15:16:54 -0800 Subject: A simpler model for repeating annotations In-Reply-To: <50EB1A31.6080207@oracle.com> References: <50E4E2F7.4060704@oracle.com> <50EAFE08.2040808@oracle.com> <50EB1A31.6080207@oracle.com> Message-ID: <5109A9E6.4070102@oracle.com> On 1/7/2013 10:55 AM, Alex Buckley wrote: > With regard to names, an advantage of getAnnotationsWithMultiples(Class) > is that it will appear after the legacy methods, which I think is better > than appearing first like getAllAnnotations(Class). Stay tuned. I give you: getAnnotationsByType(Class) - Reminiscent of getAnnotations(Class), but not an overload. - Avoids contentious phrases like "all", "repeated", and "container". - Lexicographically convenient: getAnnotation(Class) getDeclaredAnnotation(Class) getAnnotations() getDeclaredAnnotations() getAnnotationsByType(Class) getDeclaredAnnotationsByType(Class) Alex From alex.buckley at oracle.com Thu Jan 31 16:59:44 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 31 Jan 2013 16:59:44 -0800 Subject: Suggestion for additional discussion of annotation evolution vis a vis repeatability in JLS 13.5.7 In-Reply-To: <504000AC.7010202@oracle.com> References: <504000AC.7010202@oracle.com> Message-ID: <510B1380.7020900@oracle.com> On 8/30/2012 5:09 PM, Joseph Darcy wrote: > Chapter 13 of the JLS discusses binary compatibility and 13.5.7 > discussions some considerations specific to annotation types. > > I think it would be appropriate and helpful for this discussion to > include repeatability of annotation types, binary compatibility is not > changed, source and behavioral might be, etc. I'll add the act of making an annotation type repeatable to 13.5.7 as an _example_ of a change to an annotation type. However, ch.13 does not traditionally describe source or behavioral compatibility. Behavioral compatibility in this case means "the behavior of a reflective API", so the proper place to document it is in the API spec. Joel, can the following text go in the type-level javadoc of AnnotatedElement as something to be going on with: -- If an annotation of type T is present on an element, and T is made repeatable, then adding more annotations of type T to the element is source compatible and binary compatible. It is not behaviorally compatible for the get[Declared]Annotation(Class) methods and get[Declared]Annotations() methods, because they will now see only a container annotation on the element rather than any annotation of type T. It is not behaviorally compatible for the get[Declared]AnnotationsByType(Class) methods, because their results will expose the additional annotations of type T whereas previously they exposed only a single annotation of type T. If an annotation of type TC is present on an element, then making some other annotation type T repeatable (with TC as its containing annotation type) is source compatible and binary compatible. It is behaviorally compatible for the get[Declared]Annotation(Class) methods and get[Declared]Annotations() methods, in that their results will not change just because TC is a containing annotation type. However, it is not behaviorally compatible for the get[Declared]AnnotationsByType(Class) methods, because they will now recognize an annotation of type TC as a container annotation and "look through" it to expose annotations of type T. -- Alex From alex.buckley at oracle.com Thu Jan 31 18:29:09 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 31 Jan 2013 18:29:09 -0800 Subject: Spec updates for getAnnotationsByType and implicit declarations Message-ID: <510B2875.4060001@oracle.com> For repeating annotations, I adopted get[Declared]AnnotationsByType(Class) in the reflection APIs, and clarified the definitions of "directly present" and "present". For parameter reflection, I did the groundwork for "implicitly declared" constructs in the JLS, and clarified that a compiler is to mark constructs based on whether they are explicitly or implicitly declared. A compiler which emits class files can conform by utilizing the ACC_SYNTHETIC and ACC_MANDATED flags described in JVMS 4.7.22. These flags defer to a language specification for their full meaning. (It is generally better for the JVMS to provide a space which meets the requirements of what a compiler would need to represent a language construct, than the JLS saving exactly how to map a language construct into a class file. Example: the Signature attribute, JVMS 4.7.9.) The spec is at http://cr.openjdk.java.net/~abuckley/8misc.pdf as usual. Alex P.S. There was minor discussion on the GPL'd compiler-dev list about naming the ACC_MANDATED flag, starting at http://mail.openjdk.java.net/pipermail/compiler-dev/2013-January/005450.html