This message was deleted.
# community-support
s
This message was deleted.
v
Actually it is neither a valid use-case, nor a premature optimization or optimization at all. You are using
compileOnly
so it is not part of the runtime classpath. This way your convention plugin can only work if you manually (or otherwise) added the plugin to the classpath, for example with your
alias(libs.plugins.ktlint) apply false
. But that line is then just a work-around for your broken convention plugin that does not properly declare its runtime dependency.
compileOnly
is for things you need at compile time, but not at runtime. As you want to apply that plugin and also configure it using classes from it, you obviously do need it at runtime too. One use-case where you could use
compileOnly
is for example if you have annotations that you need on the compile classpath so your code compiles, but that you do not need at runtime. Either because their retention is not
RUNTIME
anyway, or if they are there for consumers that request it and thus bring it to the classpath theirselves.
s
Amazing, I had totally misunderstood it then, so much I got wrong! I think I still haven't grasped what's compile time and what's runtime in the context of Gradle. As I was thinking about it, compile time should be everything that happens before I launch my Android application, so like Gradle running, compiling the code, running all the Gradle tasks etc. Basically everything before my application is launched on my emulator. But it seems in the context of Gradle runtime is also when the build is running and configuring stuff right? I think the takeaway is to never do
compileOnly
unless I am in that very particular use case, which I doubt will happen often if ever.
v
compile time and runtime has nothing to do with Gradle context. compile time is when compiling the
.java
files to
.class
files. runtime is when executing the
.class
files. But yes, you usually pretty seldomly use
compileOnly
.
thank you 1
t
Fwiw, when you have annotations with
CLASS
retention, you'll probably want to use
compileOnlyApi
rather than
compileOnly
.
compileOnly
really only fits for annotations with
SOURCE
retention (it's older than
compileOnlyApi
, probably even older than
api
actually).
v
I don't agree.
compileOnlyApi
(besides that it is only available with the
java-library
plugin) is for classes that need to be present • at compile time • and at compile time of downstream code • but not at runtime Downstream code should not need the annotation class on its compile classpath to compile against a class that has the annotation present.
compileOnlyApi
is for real code that you need at compile time and in downstream code at compile time but not at runtime. Actually I never hit a case where I needed it so far personally.
t
Don't forget static analysis (which btw can happen at
javac
-compile-time with tools like ErrorProne or the Checker Framework).
v
I guess if they understand a particular annotation for some meaning, they should bring it to the class path themselves?
t
They could ask you to add them to the classpath (
compileOnly
, but then also
testCompileOnly
, etc.) so they could check them when present in code from dependencies, or dependencies could declare them as
compileOnlyApi
so you don't have to care about what annotations are or might be used by your dependencies when you compile against them while using static analysis tools. And don't forget the cases where the tools check annotations based on their simple name only (e.g.
@Nullable
,
@CheckReturnValue
,
@CanIgnoreReturnValue
, etc.), in this case a library defining an annotation in its own package but in a separate artifact wouldn't be correctly checked unless all downstream projects are instructed to add the annotation artifact to their classpath;
compileOnlyApi
simplifies this. Fwiw, Guava initially declared its annotation dependencies as
<optional>true</optional>
in its POM (or was it
<scope>provided</scope>
? or both? anyway, same end result) and switched to non-optional compile scope due to issues like that in downstream projects. Put differently: annotations are part of your API, so put them in
api
or
compileOnlyApi
(or
implementation
if you're not using the
java-library
, but you really should use
java-library
) unless you have good reasons not to (
compileOnly
).
thank you 1
v
Hm, I see, thanks for the info, will play a bit with it