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://github.com/ben-manes/caffeine/issues/535
I'm not a maintainer of caffeine, though I was involved in its modularization.
Regards,
Anand