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?
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.