dependency-analysis-gradle-plugin icon indicating copy to clipboard operation
dependency-analysis-gradle-plugin copied to clipboard

compileOnly: allow users to define a list of compileOnly(Api) dependencies

Open jjohannes opened this issue 10 months ago • 3 comments

Is your feature request related to a problem? Please describe.

Often projects use annotation libraries that are only required at compile time. For example: com.github.spotbugs:spotbugs-annotations

If these are placed in the compileOnly or compileOnlyApi scope, the plugin does not complain. It essential treats these as accepted alternatives to implementation or api.

However, if the dependency is missing, the plugin gives an advice like this:

These transitive dependencies should be declared directly:
  implementation("com.github.spotbugs:spotbugs-annotations:4.9.1")

In a large project, users may easily just copy/paste the advice, although in other places of the multi-project compileOnlyApi is used for the dependency.

Describe the solution you'd like

It is difficult or impossible for the plugin to tell if a dependency is still needed at runtime or not. Hence the current behavior. However, the plugin could offer a configuration option to define a list of "compile only libraries" centrally. Then, the information can be picked up when creating the advice. Something like:

dependencyAnalysis {
  structure {
    compileOnly("com.github.spotbugs:spotbugs-annotations")
  }
}

Whether it will be compileOnly or compileOnlyApi should be decided automatically:

  • If it's implementation -> compileOnly
  • If it's api -> compileOnlyApi

This is related to #1210, although the current behavior I see is the opposite to what that issue describes: I get the recommendation for implementation (see example above) although I annotated public API. Need to check.

Describe alternatives you've considered

Using the plugin in combination with https://github.com/gradlex-org/java-module-dependencies, which offers it's own post-processing task, I could offer such a solution in the extension of that plugin. But I would prefer to offer this to all users of DAGP.

jjohannes avatar Feb 28 '25 09:02 jjohannes

Thanks for the issue. I think this makes sense and would be a useful enhancement for this plugin.

I think for it to be considered feature-complete, we need to take into account the reason task. I have recently been doing this whenever making improvements or fixing bugs. A specific concern regarding reason and compileOnlyApi is that this plugin currently has no support for that configuration. There might be a significant amount of plumbing to do to "make it work." That could be done across several PRs to simplify review.

Please also note that I don't think that all the plugins this plugin supports (Android, Java, Kotlin, a few others) themselves support that configuration. Or maybe they all do and it's a non-issue. But if for example Android doesn't support compileOnlyApi, then we need to ensure we don't suggest it.

autonomousapps avatar Mar 03 '25 21:03 autonomousapps

My hope is, that this issue is simply obsolete regarding annotations if #1210 gets fixed. Because then libraries that are only used to annotate something or as arguments to annotations should always only be recommended as compileOnly, no matter what their retention is.

I'm actually only aware of one rare use-case where compileOnlyApi is appropriate. If you have types in your public API (not annotations, real public API things) that are expected to be there in the final runtime environment, so should not be part of the dependencies. So basically things that are part of the public API like superclass or return type and so on, but are "provided" by the final runtime environment. Those are compileOnlyApi as the downstream projects needs them at compile time to not fail compilation. For those it would be nice to have some configuration. Currently you would need to use onIncorrectConfiguration to suppress the advice and then might miss valid advices that result from code changes.

Vampire avatar Jul 16 '25 10:07 Vampire

I'm actually only aware of one rares use-case where compileOnlyApi is appropriate.

I somewhat recently ran into just such a situation at work. I don't know how common it is in general, but I agree it's a real use-case that is worth supporting here.

autonomousapps avatar Jul 16 '25 19:07 autonomousapps