Skip to content

Do not publish the Spring Boot BOM to consumers (#194) - #198

Open
JangHyeok2909 wants to merge 1 commit into
gavlyukovskiy:masterfrom
JangHyeok2909:fix/do-not-publish-spring-boot-bom
Open

Do not publish the Spring Boot BOM to consumers (#194)#198
JangHyeok2909 wants to merge 1 commit into
gavlyukovskiy:masterfrom
JangHyeok2909:fix/do-not-publish-spring-boot-bom

Conversation

@JangHyeok2909

Copy link
Copy Markdown

Fixes #194

The Spring Boot BOM is currently declared with implementation(platform(...)). Since implementation is part of the published runtimeElements variant, the BOM is propagated to consumers.

// runtimeElements of datasource-decorator-spring-boot-autoconfigure-1.12.1.module
{
  "group": "org.springframework.boot",
  "module": "spring-boot-dependencies",
  "version": { "requires": "3.5.7" },
  "attributes": { "org.gradle.category": "platform" }
}

As a result, every consumer that resolves dependencies through Gradle metadata inherits Spring Boot's entire dependency management. In #194, an application on Spring Boot 3.4.5 had its Prometheus dependencies upgraded by the 3.5.7 BOM shipped with this library, which failed at runtime with NoSuchMethodError.

However, spring-boot, spring-boot-autoconfigure and spring-boot-jdbc are declared without a version and take it from the BOM, so removing only the platform declaration makes the publication invalid.

Invalid publication 'mavenJava':
  - Publication only contains dependencies and/or constraints without a version.

The Spring Boot modules are therefore declared as compileOnly, and the BOM is kept only on configurations that are not published (compileOnly, annotationProcessor, testImplementation). Version alignment inside the build is unchanged, and nothing Spring Boot related is published anymore. Note that this is a behaviour change: the published artifacts no longer carry any Spring Boot dependency.

This is the same approach used by opentelemetry-spring-boot-starter and resilience4j-spring-boot3. Anything using this library is a Spring Boot application and always brings its own Spring Boot, so not publishing the BOM is the more appropriate behaviour.

Below is the result observed from a consumer on Spring Boot 4.0.0, while this library is built against 4.0.6.

runtimeClasspath
+--- org.springframework.boot:spring-boot-dependencies:4.0.0
|    +--- org.springframework.boot:spring-boot-starter-jdbc:4.0.0 (c)
|    +--- org.springframework.boot:spring-boot-jdbc:4.0.0 (c)
|    +--- org.springframework.boot:spring-boot-autoconfigure:4.0.0 (c)
|    +--- org.springframework.boot:spring-boot:4.0.0 (c)
\--- com.github.gavlyukovskiy:p6spy-spring-boot-starter
     +--- com.github.gavlyukovskiy:datasource-decorator-spring-boot-autoconfigure
     \--- p6spy:p6spy:3.9.1

spring-boot is selected as 4.0.0, the version declared by the consumer, and 4.0.6 does not appear anywhere in the runtime graph.

Verification

  • ./gradlew build passes, including the three sample applications, which consume the artifacts published to mavenLocal.
  • Neither the published .module nor the .pom of the autoconfigure module and the starters contains a platform dependency.

Declare the Spring Boot modules as compileOnly and keep the BOM only on
configurations that are not published, so that neither the BOM nor the
Spring Boot dependencies end up in the published variants.

Fixes gavlyukovskiy#194
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Published Gradle metadata leaks spring-boot-dependencies BOM as a transitive platform dependency

1 participant