Question for Mike re: changing containers
michael keith
michael.keith at oracle.com
Thu Mar 7 23:47:38 PST 2013
On 07/03/2013 8:05 PM, Alex Buckley wrote:
> If you change:
>
> @Repeatable(FooContainer.class)
> @interface Foo {...}
>
> to:
>
> @Repeatable(OtherContainer.class)
> @interface Foo {...}
>
> then getAnnotationsByType(Foo.class) will seek out @OtherContainer.
> Any @FooContainer (generated by a compiler to wrap @Foo @Foo prior to
> the change) will be ignored. So, switching Foo's containing annotation
> type is behaviorally incompatible for reflective clients.
My point was only that the processing client code does not and should
not change regardless of the container type when using the look-through
methods. Clearly, processing a precompiled annotated class is not going
to find the contained annotation if the container annotation has been
changed in the interim. However, I think one would have to accept that
after changing the container annotation one would have to recompile the
annotated classes with the updated annotations.
>
> There is no way around that, but actually, it wasn't what I meant to
> ask you!
>
> Suppose FooContainer is intended to be the containing annotation type
> for Foo forever. Do you ever tweak FooContainer's declaration, for
> example, expanding its applicability (adding entries to @Target) ?
The elements of the annotation do not ever change for us from one
release to another (we only ever have a single value() element that
consists of an array of the contained annotation type) but modifying the
meta-annotations of the containing annotation is something that can
happen occasionally as they may get expanded on the contained
annotation. Adding an entry to @Target is a good example, where an
annotation is being extended to be allowed to be present on additional
code elements.
>
> I ask because Joel and I are wondering how strict to be in
> getAnnotationsByType(Class) if FooContainer diverges slightly from
> Foo's expectations. No doubt FooContainer will be a proper "containing
> annotation type" for Foo almost all the time, since you can't compile
> @Foo @Foo otherwise - but maybe someone makes a mistake, where
> @Inherited is removed from FooContainer but not Foo, and then @Foo
> @Foo isn't inherited because @FooContainer isn't inherited - this
> would cause a subtle change in client behavior. I think we're heading
> towards saying this is just "OK", rather than raising an
> AnnotationFormatError.
As I think I mentioned in the past, I think the real annotation
development happens on Foo, and the container annotation must get
changed to match. In other words it is far more likely that I would
change @Inherited on @Foo but forget to do so on @FooContainer. Anyway,
that isn't really your question either ;-)
My experience is that the meta-annotations on the container annotation
should match exactly what is on the contained annotation (with the
possible exception that I might only want @Documented to be on @Foo and
not on @FooContainer, if that worked :-). In all other cases I would
expect to be told at compile-time since it is likely an oversight if
they don't match. I don't know that it is that important to catch at
runtime, though, and I would likely opt out of the extra checking if it
cost me some performance.
> tl;dr There are many rules tying FooContainer to Foo, and maybe they
> just don't matter much at run-time.
>
> Alex
>
> On 3/6/2013 11:10 PM, michael keith wrote:
>> Our usage of the container annotation has fairly consistently been a
>> trivial mapping from the singular contained annotation to its pluralized
>> containing form. We have, during development, changed the name of the
>> singular annotation and then had to go and rename the container
>> annotation to the plural form of the newly named singular one, but it
>> would not be common at all to decide to rename the container one
>> independent of the singular one, and I am talking about development,
>> before clients exist.
>>
>> Existing clients of the current getAnnotation(Class) and
>> getAnnotations() methods are written to reference both the repeatable
>> and the container annotations directly, so renaming either one of them
>> would be a breaking change that we would not generally undertake after
>> the annotations have been created/released.
>>
>> I would not have expected a precompiled client of
>> getAnnotationsByType(Foo.class) to be affected by such a change, though.
>> The container annotation is meant to be transparent to them, isn't it?
>>
>> -Mike
>>
>> On 06/03/2013 8:22 PM, Alex Buckley wrote:
>>> Mike, we're pondering whether the new methods in core reflection
>>> should be strict about the relationship of containing type to
>>> repeatable type.
>>>
>>> Have you ever written @FooContainer({@Foo(1),...}) on a declartion,
>>> and later changed it to @OtherContainer({@Foo(1),...}) ? The effect on
>>> clients using getAnnotation(Class) and getAnnotations() would be
>>> significant.
>>>
>>> Effectively we are wondering if a client using
>>> getAnnotationsByType(Foo.class) should be affected by such a change.
>>>
>>> Alex
>>
More information about the enhanced-metadata-spec-discuss
mailing list