[External] : Re: Annotation Dependencies and Requires Static Transitive

Alex Buckley alex.buckley at oracle.com
Tue Jul 6 17:43:05 UTC 2021


Presumably this is a javac lint warning about how types referenced from 
an exported API (e.g., the return type of an exported public method) 
should themselves be exported.

It's hard to tell from 
https://docs.oracle.com/en/java/javase/16/docs/specs/man/javac.html#option-Xlint-custom 
exactly which kind of warning it is, but `exports` is plausible.

Types of annotations on the exported API should probably be excluded 
from that lint check, what ever the retention policy of those annotation 
types. (This feels like something that's come up before...)

Alex

On 6/7/2021 4:45 AM, Anand Beh wrote:
> Thanks to you both for the advice.
> 
> Following on your suggestions, Caffeine changed to "requires static".
> However, javac now produces a warning about the lack of transitivity:
> 
> warning: [exports] class Nullable in module
> org.checkerframework.checker.qual is not indirectly exported using
> requires transitive
> 
> Is this a bug in javac or is it anything we should be worried about?
> 
> Regards,
> Anand
> 
> On 6/3/21, Alex Buckley <alex.buckley at oracle.com> wrote:
>> Even without `transitive`, requiring modules with `static` means that
>> anyone who habitually builds their entire stack from source will still
>> need the errorprone and checker-qual modules at compile time.
>>
>> There are no "run-time only" dependencies in module declarations, unless
>> services come into play, which is not realistic here. As Remi said,
>> `requires static` is your best bet. Annotation types that are exported
>> by a third party such as Google, in order for people to annotate their
>> personal codebases, are not really an API that those personal codebases
>> need to export -- any fourth party program that wishes to inspect the
>> annotations in your codebase needs to arrange its own dependency on the
>> annotation types from the third party.
>>
>> Alex
>>
>> On 6/3/2021 1:10 PM, Anand Beh wrote:
>>> Hello,
>>>
>>> The cache library Caffeine recently added a full module descriptor. It
>>> has no runtime dependencies, but it depends on metadata annotations
>>> from checker-qual and errorprone, for example @NotNull and
>>> @CanIgnoreReturnValue. The module looks like this:
>>> module com.github.benmanes.caffeine {
>>>     exports com.github.benmanes.caffeine.cache;
>>>     exports com.github.benmanes.caffeine.cache.stats;
>>>
>>>     requires static transitive com.google.errorprone.annotations;
>>>     requires static transitive org.checkerframework.checker.qual;
>>> }
>>>
>>> The annotations are not required at runtime, hence static. They're
>>> visibly placed on public methods and return types, so that API clients
>>> can benefit from them for the purposes of annotation-based null
>>> analysis, kotlin interop, etc. As the annotations are part of the API,
>>> they're marked transitive.
>>>
>>> However, the "transitive" aspect imposes some requirements on users. I
>>> am wondering if there is a more correct way to declare these
>>> annotation dependencies than static transitive.
>>>
>>> One user would like to avoid the presence of these annotations at
>>> compile-time. For reference, here's the relevant discussion:
>>> https://urldefense.com/v3/__https://github.com/ben-manes/caffeine/issues/535__;!!GqivPVa7Brio!P53mZvzj_tIsON7Z_5P-tzQ-IH1xOgXbL9XWhtMKgoiJj97GfzXgrsvPc8Z27rHccoc$
>>>
>>> I'm not a maintainer of caffeine, though I was involved in its
>>> modularization.
>>>
>>> Regards,
>>> Anand
>>>
>>


More information about the jigsaw-dev mailing list