RFR: 8231436: Fix the applicability of a no- at Target annotation type

Brian Goetz brian.goetz at oracle.com
Tue Feb 9 14:34:41 UTC 2021

We appear to have painted ourselves into a corner quite nicely.

In Java 5, the interpretation of "a no- at Target annotation (NTA) is 
applicable in all contexts" made perfect sense; you could use the 
@Target meta-annotation to narrow the set of targets if you were fussy.  
Then along came type annotations, and we picked the sensible rule that 
the default for an NTA would be all _declaration_ annotations.  This 
avoided short-term incompatibility, but what it did was set type 
annotations apart from all the other places where annotations can go.

I agree with Joel that:
> I agree that had we done this in one go from scratch, it seems likely that the “all contexts” default for no- at Target annotation would have been chosen.
but, we didn't do this in one go from scratch.  I also agree with Joe 
that the reality seems to be that "one of these things is not like the 
others", and that this is a decision best made by the author of the 

> To me, it seems that intending an annotation to be used on 
> declarations or on types is a basic design decision of the annotation 
> type. 

The concern now seems mostly to be about "but, there are old moldy 
annotations (most of them some spelling of "non null"), that we'd like 
to be applicable in all places, but were written without a @Target, but 
which we'd like to interpret as type annotations." Understandable, but 
it seems that the fix for that is to convince the maintainers of those 
annotations of this fact, not change the language to absolve them from 
responsibility for updating their design intent in their code.

So I agree with Joe that:

> I think it can be reasonable to interpret lack of @Target to mean 
> "usable in any declaration context," but ill-advised to silently 
> reinterpret absence of a @Target to indicate types and declarations. 

and prefer that we leave the existing interpretation of "all declaration 
contexts" for NTAs.  Like raw types, which we convinced ourselves we 
could get rid of eventually, sometimes this turns out to be wishful 

On 2/3/2021 1:39 PM, Alex Buckley wrote:
> Let me focus first on the design question of what a no- at Target 
> annotation type "means". There's no particular reason why it 
> _shouldn't_ mean "all contexts". Mike gave good reasons why it should 
> mean that. For the corner case of an annotation appearing in one of 
> the ambiguous locations in source code, the annotation will appear in 
> the class file/via reflection exactly as if someone had taken the 
> perfectly legitimate course of spelling out @Target({METHOD, 
> TYPE_USE}) -- the no- at Target case is not a secret door to behavior 
> that's otherwise impossible or undesirable.
> (We could have said "all contexts" for a no- at Target annotation type 
> but then added a rule in 9.7.4 to special-case a no- at Target annotation 
> that appears in an ambiguous location, e.g., to compile the annotation 
> as if it was applicable only in declaration contexts. More 
> compatibility with SE 8, but more complexity, and I don't think anyone 
> really wants that.)
> Turning to the compatibility concern: yes, JDK-8231435 shouldn't have 
> claimed behavioral compatibility. It was my error to not recognize 
> what Mike was saying in "It is a behavior change from the current 
> specification, but a small one that affects poorly-written programs 
> that have no @Target meta-annotation." Still, at the end of the day, 
> it's no more than a small behavioral incompatibility for annotation 
> processors (they may see more type annotations than they did before), 
> and one which was within the power of the annotation type's owner to 
> induce anyway (annotation processors that look for type annotations 
> can reasonably be expected to ignore type annotations in places they 
> don't care about).
> I have cc'd Mike in case he wants to add anything further, but the 
> design intent of "all contexts" still looks reasonable to me.
> Alex
> On 2/3/2021 5:29 AM, Joel Borggren-Franck wrote:
>> Hi Alex,
>> Looking at  the class file, and therefore reflection, there is a 
>> difference between “all declaration contexts” and “all contexts, 
>> declaration + type”. For the 5 ambiguous locations we would have to 
>> produce type annotation attributes if there is an annotation present 
>> whose declaration lack @Target. While this may or may not be 
>> desirable, and I’m leaning towards not, it is surely significant as 
>> it would change the semantics of reflective annotation processors in 
>> use.
>> cheers
>> /Joel
>>> On 2 Feb 2021, at 19:50, Alex Buckley <alex.buckley at oracle.com> wrote:
>>> I initially proposed "all declaration contexts" as the smallest 
>>> possible streamlining of the SE 7-oriented rule defined in SE 8. It 
>>> would have ensured that legacy annotation types without @Target were 
>>> locked out of the new world of type uses enabled in SE 8 by JSR 308. 
>>> As it turned out, my conservative approach was unnecessary because 
>>> Mike was fine with admitting those legacy annotation types for type 
>>> uses via the "all contexts" rule. In the real world, "all 
>>> declaration contexts" versus "all declaration contexts + all type 
>>> contexts" is a distinction without a difference (that is, an 
>>> insignificant distinction) -- we're best off adopting the latter 
>>> rule, phrased simply as "all contexts".
>>> Alex
>>> On 2/2/2021 3:44 AM, Guoxiong Li wrote:
>>>> On Tue, 2 Feb 2021 09:28:59 GMT, Joel Borggrén-Franck 
>>>> <jfranck at openjdk.org> wrote:
>>>>>> Thanks for the comments,
>>>>>> @jbf I'll add a more focused test. For the bug, the original 
>>>>>> discussion in 
>>>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2019-September/013705.html 
>>>>>> is specifically about annotations without an explicit `@Target` 
>>>>>> applying to `MODULE`, I don't think there's anything that needs 
>>>>>> to be done for 
>>>>>> [JDK-8231436](https://bugs.openjdk.java.net/browse/JDK-8231436) 
>>>>>> besides supporting `MODULE`, would you still prefer a separate bug?
>>>>>> @jddarcy note that there was already a spec change related to 
>>>>>> this in 
>>>>>> [JDK-8231435](https://bugs.openjdk.java.net/browse/JDK-8231435) 
>>>>>> and the spec bug mentions "this expansion is source, binary, and 
>>>>>> behaviorally compatible", should I still file a CSR?
>>>>>  From this follow up here: 
>>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2019-September/013715.html 
>>>>> my interpretation is that this bug was intended to widen it to all 
>>>>> contexts, including type use. This has been changed in JLS but not 
>>>>> in the normative javadoc and also not in the compiler. I believe 
>>>>> we should keep declarations only, and back out the change to JLS.
>>>> Maybe we should collect the concrete information about this 
>>>> problem. Here are some materials that I know.
>>>> Order by time:
>>>> - 2019.08 **Werner Dietl** launched the discussion. [1]
>>>> - 2019.09 After the discussion between **Alex Buckley** and 
>>>> **Michael Ernst**, an initiative result came out.[2]
>>>> - 2019.09 Two JBS issues were filed. [3][4]
>>>> - 2019.12 **Alex Buckley** fixed the JLS(fix version: 14). But the 
>>>> compiler code and javadoc were not fixed. [5][6]
>>>> - 2020.10 **Christian Stein** created another issue about it. [7]
>>>> - 2020.10 **Guoxiong Li**(me) submitted a PR about it in Github. [8]
>>>> - 2020.10 **Joel Borggrén-Franck** restarted the discussion about 
>>>> the specification. [9]
>>>> - 2020.12 Because the JDK16 was nearly at RDP1, we decided to only 
>>>> fix JDK-8254023. And other work left to JDk17. [7][10][11]
>>>> - 2020.12 The issue JDK-8254023 was fixed at JDK16. [7][8][12]
>>>> - **Now, we need to discuss the problem(unify the specification, 
>>>> implement and javadoc) that JDK16 has left.**[11]
>>>> [1] 
>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2019-August/013666.html
>>>> [2] 
>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2019-September/013705.html
>>>> [3] https://bugs.openjdk.java.net/browse/JDK-8231435
>>>> [4] https://bugs.openjdk.java.net/browse/JDK-8231436
>>>> [5] 
>>>> https://docs.oracle.com/javase/specs/jls/se14/html/jls-9.html#jls-
>>>> [6] 
>>>> https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/annotation/Target.html
>>>> [7] https://bugs.openjdk.java.net/browse/JDK-8254023
>>>> [8] https://github.com/openjdk/jdk/pull/622
>>>> [9] 
>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2020-October/015197.html
>>>> [10] http://openjdk.java.net/projects/jdk/16/
>>>> [11] 
>>>> https://mail.openjdk.java.net/pipermail/compiler-dev/2020-December/015503.html
>>>> [12] https://github.com/openjdk/jdk16/pull/34
>>>> -------------
>>>> PR: https://git.openjdk.java.net/jdk/pull/2303

More information about the compiler-dev mailing list