Alban Dericbourg
Alban Dericbourg

Reputation: 1636

Use BOM from Gradle plugin management

We use a BOM to share our dependency management in MyCompany.

It is defined as a Maven POM. Here is a minimal example:

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.common</groupId>
  <artifactId>common-java</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>

  <properties>
    <spring-boot.version>2.4.0</spring-boot.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

</project>

It is then used from Gradle projects.

Although this works for code dependencies, I'd like to find out a way to use it from plugin management.

For now, we define in settings.gradle.kts:

pluginManagement {

    val springBootVersion: String by settings

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

springBootVersion being defined in the gradle.properties.

This is an issue to me because Spring version is defined both:

How can I access to that BOM from Gradle's plugin management? And if I can't, what is a good don't-repeat-yourself practice to do so?

Upvotes: 4

Views: 2437

Answers (1)

Jacob Wallace
Jacob Wallace

Reputation: 927

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.

Upvotes: 2

Related Questions