Gradle plugin for JVM projects written in Java, Kotlin, Groovy, or Scala; and Android projects written in Java or Kotlin. Provides advice for managing dependencies and other applied plugins
Apache License 2.0
1.66k
stars
116
forks
source link
Annotations used to annotate and things (enum constants, class literals, ...) used for annotation member values should not count to ABI #1210
reason output for bugs relating to incorrect advice
----------------------------------------
You asked about the dependency 'com.fasterxml.jackson.core:jackson-annotations:2.17.1'.
There is no advice regarding this dependency.
----------------------------------------
Shortest path from root project to com.fasterxml.jackson.core:jackson-annotations:2.17.1 for compileClasspath:
:
\--- com.fasterxml.jackson.core:jackson-annotations:2.17.1
There is no path from root project to com.fasterxml.jackson.core:jackson-annotations:2.17.1 for runtimeClasspath
There is no path from root project to com.fasterxml.jackson.core:jackson-annotations:2.17.1 for testCompileClasspath
There is no path from root project to com.fasterxml.jackson.core:jackson-annotations:2.17.1 for testRuntimeClasspath
Source: main
------------
* Exposes 1 class: com.fasterxml.jackson.annotation.JsonIgnore (implies api).
Source: test
------------
(no usages)
Describe the bug
Annotations used to annotate and things (enum constants, class literals, ...) used for annotation member values should not be part of the ABI / always be compileOnly, no matter what retention the annotation has.
Annotations are never necessary to be in the compile classpath or runtime classpath of any downstream projects just for being present in the class file / at runtime.
The annotation parser that processes annotations in the class file just skips annotations for which the class is not present.
If some code wants to retrieve the annotation from a piece of code, then that "some code" is responsible to also have the annotation added to the classpath.
Expected behavior
Annotations that are only used to annotate stuff, and things only used for annotation member values like class literaly, enum constants, ... should always be considered and recommended compileOnly.
Currently in the given example the advice is to change to api because a public method is annotated.
If a private method or field is annotated, implementation is advised.
If an annotation is of course used in some other way, like as class literal outside an annotation member value, or as variable type, or as return type, or as parameter type and so on, then advising as implementation or api is perfectly correct of course.
Additional context
Another example would be, if you develop a library that works stand-alone but is also DI friendly, supporting Spring, CDI, and Guice.
The library developer adds annotations for all three frameworks to this class.
All those annotations are runtime retention.
But you do not want to enforce any specific or any at all on downstream projects.
Imho annotations that are only used to annotate things (and of course then also the types used for the annotation member values) should always be compileOnly.
In case you strongly disagree with this and without any chance to be convinced to change the logic, please at least provide some feature-switch to treat it like described here.
Plugin version 1.32.0
Gradle version 8.8
JDK version 17
reason
output for bugs relating to incorrect adviceDescribe the bug Annotations used to annotate and things (enum constants, class literals, ...) used for annotation member values should not be part of the ABI / always be
compileOnly
, no matter what retention the annotation has.Annotations are never necessary to be in the compile classpath or runtime classpath of any downstream projects just for being present in the class file / at runtime. The annotation parser that processes annotations in the class file just skips annotations for which the class is not present.
If some code wants to retrieve the annotation from a piece of code, then that "some code" is responsible to also have the annotation added to the classpath.
To Reproduce
Expected behavior Annotations that are only used to annotate stuff, and things only used for annotation member values like class literaly, enum constants, ... should always be considered and recommended
compileOnly
.Currently in the given example the advice is to change to
api
because a public method is annotated. If a private method or field is annotated,implementation
is advised.If an annotation is of course used in some other way, like as class literal outside an annotation member value, or as variable type, or as return type, or as parameter type and so on, then advising as
implementation
orapi
is perfectly correct of course.Additional context Another example would be, if you develop a library that works stand-alone but is also DI friendly, supporting Spring, CDI, and Guice. The library developer adds annotations for all three frameworks to this class. All those annotations are runtime retention. But you do not want to enforce any specific or any at all on downstream projects.
Imho annotations that are only used to annotate things (and of course then also the types used for the annotation member values) should always be
compileOnly
. In case you strongly disagree with this and without any chance to be convinced to change the logic, please at least provide some feature-switch to treat it like described here.