Slackbot
08/20/2022, 11:09 PMVampire
08/20/2022, 11:42 PMcompileOnly
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.Stylianos Gakis
08/21/2022, 9:17 AMcompileOnly
unless I am in that very particular use case, which I doubt will happen often if ever.Vampire
08/21/2022, 9:52 AM.java
files to .class
files.
runtime is when executing the .class
files.
But yes, you usually pretty seldomly use compileOnly
.Thomas Broyer
08/21/2022, 4:35 PMCLASS
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).Vampire
08/21/2022, 5:28 PMcompileOnlyApi
(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.Thomas Broyer
08/21/2022, 5:39 PMjavac
-compile-time with tools like ErrorProne or the Checker Framework).Vampire
08/21/2022, 5:41 PMThomas Broyer
08/21/2022, 5:59 PMcompileOnly
, 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
).Vampire
08/21/2022, 8:05 PM