Make use of (published) platform in (published) convention plugin

I have three projects:

  1. A Gradle platform, published on Maven Central. I can use this to define versions of some plugins and libraries, which works as expected.
  2. A Java project. Nothing fancy. Makes use of some libraries, and runs things like errorprone/CPD/PMD/CheckStyle/… during build.
  3. A collection of convention plugins (which, previously, were defined in the Java project’s buildSrc/src/main/kotlin/foo.gradle.kts).

I’d like to use the convention plugins (#3) in my Java project(s) (#2) so that I can quickly setup similar Java projects without having to copy-paste the convention plugins.

The outstanding issue is that I’d like to use versions defined in the platform (#1) inside my convention plugins. One example is running errorprone as part of the build. For this, my convention plugin includes:

plugins {

dependencies {

With this, errorprone is activated once the convention plugin is included, and the error_prone_core dependency is added to the corresponding configuration. The version of error_prone_core is defined in my platform, which I included in my build.gradle.kts (in #3):

dependencies {

However, while this platform is used to derive the version of, for example, the net.ltgt.errorprone plugin, the platform is not “exported” to my Java project (#2). In fact, building the Java project fails with (at least) two errors:

Could not determine the dependencies of task ':application:compileJava'.
> Could not resolve all task dependencies for configuration ':application:annotationProcessor'.
   > Could not find de.c-otto:java-platform:.
     Required by:
         project :application
   > Could not find
     Required by:
         project :application

How can I create pre-compiled & published convention plugins making use of some platform, without having to define the dependency details for (in this example) errorprone myself?

I tried defining the platform version inside the platform itself, which didn’t help.

However, it works if I add this to my conventions project (in settings.gradle.kts):

dependencyResolutionManagement {

However, it does not work if I include my platform via the mavenLocal() repository.

What’s the relevant magic of includeBuild?

This only worked because I also used includeBuild from my Java project to my conventions project, which added the platform transitively. If I include the conventions via mavenLocal() I get the same errors, even if I use includeBuild for the conventions project to include the platform project.

I think the problem is, that you do not define a version for the platform in the convention plugin.
So when you apply the convention plugin to the Java project, Gradle does not know which version of the platform to use.
Having the platform in the convention plugins build just cares about the dependencies of your plugin, but not about the dependencies your plugin adds to the project it is applied to.

Yes, that seems to be it, thank you! Is there way to define the version just once (like a global variable?) so that I can re-use it everywhere I need to inside my conventions plugin project to avoid duplicating the version (and, possibly, forgetting to update one of the duplicates in the near future)?

I think I need the platform version both for the convention plugin’s build logic (so that I can make use of plugins like “gradle-cpd-plugin” without specifying the version), and for the actual convention plugin scripts (so that users of my convention plugins don’t need to specify versions to libraries known in my platform).

Maybe add a published version catalog that you then can use everywhere?

Sounds like a plan… those are more flexible than exported platforms?

They are different and can even work together. A version catalog is just a catalog of coordinates and versions to pick from. A platform influences resolution and can also be published as dependency.

1 Like