4

I really like the Gradle java-platform feature. I've created my own platform that bundles spring-boot-dependencies along with other things. Now I have (shortened for clarity):

plugins {
    id 'org.springframework.boot' version '2.4.1'
}

dependencies {
    implementation platform("my-group:my-base-bom:1.0.0")
}

And I'd like the spring boot plugin version to automatically adjust to match the version of spring-boot-dependencies that is bundled in my platform (so if the platform went to SB 2.5.0 then plugin would do the same without my needing to change the build.gradle.

I can't figure out how to do it though without resorting to external variables. Is it possible?

  • I was trying to do the exact same thing and I solved my problem publishing a "version-catalog" (see https://docs.gradle.org/current/userguide/platforms.html#sec:version-catalog-plugin) and defining my platform constraints based on that same version-catalog (see the final code of the same documentation page https://docs.gradle.org/current/userguide/platforms.html#sub:platforms-vs-catalog). – Daniel Schröder Aug 22 '22 at 17:30

2 Answers2

2

Not possible. Currently, there are (3) ways to define versions for plugins:

In the Gradle file directly:

// build.gradle.kts

plugins {
    id("org.springframework.boot") version "2.4.1"
}

In the plugins dependencies spec:

// settings.gradle.kts

pluginManagement {
    plugins {
        id("org.springframework.boot") version "2.4.1"
    }
}

or with a resolution rule:

// settings.gradle.kts

pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == "org.springframework.boot") {
                useVersion("2.4.1")
            }
        }
    }
}

All of which do not accept a platform, only a single version variable.

Another way I tested, but ultimately did not work was utilizing the buildscript:

// build.gradle.kts

buildscript {
    dependencies {
        classpath(platform("io.mateo.sample:platform-bom:1.0.0-SNAPSHOT"))
        classpath("org.springframework.boot:spring-boot-gradle-plugin")
    }
}

As mentioned at the start, it's not possible.

Cisco
  • 20,972
  • 5
  • 38
  • 60
  • okay, I'll wait to see if I get any solutions before accepting this, but thanks. – Dennis Doubleday Jan 27 '21 at 18:39
  • Is this answer still valid today? We've had quite a lot of Gradle versions in the last year. Do you know if anything changed in regards of applying a plugin with its version defined though a platform? – Daniel Schröder Aug 22 '22 at 17:40
2

Your custom platform can provide an opinion about which version of the Spring Boot Gradle plugin you want clients to use (especially since it's not included in the spring-boot-dependencies BOM).

Here are the relevant parts of an example platform's build.gradle.kts file, for example:

plugins {
    `java-platform`
}

javaPlatform {
    allowDependencies()
}

dependencies {

    // This platform extends the Spring Boot platform.
    api(platform("org.springframework.boot:spring-boot-dependencies:2.7.6"))

    constraints {
        // Provide an opinion about which version of the Spring Boot Gradle plugin clients
        // should use since it's not included in the standard spring-boot-dependencies BOM.
        api("org.springframework.boot:spring-boot-gradle-plugin:2.7.6")
    }

}

That will generate a BOM that aligns both spring-boot-gradle-plugin and spring-boot-dependencies:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-gradle-plugin</artifactId>
            <version>2.7.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.7.6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Your client projects can then just depend upon your platform and inherit its opinion about the Spring Boot version using something like this:

buildSrc/build.gradle.kts:

// Pull in the version of the Spring Boot Gradle plugin specified by your
// platform, making it available to your regular build script.
dependencies {
    implementation(enforcedPlatform("my-group:my-base-bom:1.0.0"))
    implementation("org.springframework.boot:spring-boot-gradle-plugin")
}

build.gradle.kts:

plugins {
    id("org.springframework.boot") // version inherited from your platform
}

dependencies {
    // It's necessary to specify it for each configuration.
    implementation(enforcedPlatform("my-group:my-base-bom:1.0.0"))

    // Pull in any normal Spring Boot-managed dependencies you need (versions come from platform).
    implementation("org.springframework.boot:spring-boot-starter-web")
}

Of course, you could also use Gradle version catalogs to centralize versions, which are inlined for clarity in the examples.

Jacob Wallace
  • 887
  • 2
  • 12
  • 24
  • This worked for me. You can see an example of this in https://docs.gradle.org/current/userguide/structuring_software_products.html where "plugins-platform" platform defines the `org.springframework.boot:org.springframework.boot.gradle.plugin` version. – Johannes Rudolph Feb 27 '23 at 21:36