compileOnly transitive

I’m interested in adopting the new compileOnly approach. However for our existing gradle build configurations we rely fairly heavily on the dependencies being transitive (we have a large multi-module build). I have tried adjusting the base configuration for compileOnly to be transitive as indicated in the docs, but this does not seem to make any difference. My downstream modules are still failing to compile. Can you advise how this might be achieved?

My understanding of compileOnly is that these dependencies are only neccessary to compile the current project and therefore must not be transitive. If another project also needs those dependencies for compiling they should be declared explicitely at that project. By doing so, there is no need for them to be transitive.

What if my project looks like this:

war-project --> subprojectA (jar) --> subprojectB (jar) -?-> servlet-api.jar
If several war projects are indirectly using subprojectB and I don’t want to duplicate the dependency on the servlet-api, then compileOnly does not help (because it’s only visible to subprojectB) and compile puts it into the war. IMHO this would be a good reason for transitive compileOnly dependencies.

If each of the subprojects needs the servlet-api for compiling then each of the subprojects must have its own dependency on the servlet-api. Otherwise the situation could occur that e.g. subprojectB doesn’t need the dependency anymore and removes it from its dependencies resulting in compilation errors of subprojectA.
Those situations can occur more often if some of the projects are handled by third-party developers. Never rely on dependencies of others if you need that dependency by yourself.

2 Likes