Skip to content

Inherit Spring Boot managed dependency versions in grails-bom#15730

Open
jamesfredley wants to merge 2 commits into
8.0.xfrom
deps/grails-bom-inherit-spring-managed
Open

Inherit Spring Boot managed dependency versions in grails-bom#15730
jamesfredley wants to merge 2 commits into
8.0.xfrom
deps/grails-bom-inherit-spring-managed

Conversation

@jamesfredley

Copy link
Copy Markdown
Contributor

What

Stop maintaining grails-bom version pins that duplicate versions already managed by the spring-boot-dependencies BOM (Spring Boot 4.1.0). Where our pin equals Spring Boot's managed version, the pin is dead weight: it only blocks free patch/security updates whenever Spring Boot bumps the dependency. Those pins are removed so the BOM inherits the version from Spring Boot.

Fixes #15674

Note: the issue was drafted against Spring Boot 4.0.6. This PR re-audits against the 4.1.0 BOM actually on 8.0.x, so the SAME/DIVERGENT buckets differ from the issue (e.g. commons-lang3 and byte-buddy have since converged with Spring Boot and are now removable).

Removed (each equal to Spring Boot 4.1.0's managed version)

Pin Version How it's still managed
byte-buddy (+ byte-buddy-agent) 1.18.10 spring-boot-dependencies
commons-codec 1.21.0 spring-boot-dependencies
commons-lang3 3.20.0 spring-boot-dependencies
jakarta.servlet-api 6.1.0 spring-boot-dependencies
jakarta.validation-api 3.1.1 spring-boot-dependencies
junit / junit-jupiter (12 junit-* entries + junit-bom platform import) 6.0.3 Spring Boot already imports junit-bom:6.0.3
mongodb (bson, driver-core, driver-sync, bson-record-codec) 5.8.0 spring-boot-dependencies
rxjava3 3.1.12 spring-boot-dependencies

Also removed the jakarta.servlet / jakarta.validation excludes from grails-bom/base/build.gradle - they only existed to win a since-resolved selenium-vs-Spring-Boot conflict, and both versions now match Spring Boot.

Kept intentionally

  • graphql-java 25.0 - retained as a deliberate drift tripwire (rationale comment added), because graphql-java-extended-scalars is not managed by Spring Boot and must move in lockstep.
  • groovy 4.0.32 - intentional major divergence vs Spring Boot's 5.0.6 (Grails 8 baseline / Spock 2.4-groovy-4.0).
  • selenium 4.38.0 - left pinned. It is now behind Spring Boot's 4.43.0, so dropping it would be a version bump (Geb/functional impact), not a pure inheritance. Worth a separate follow-up decision.
  • spring-retry 2.0.11 - Spring Boot 4 dropped management.

Legacy CLI fix (required so this doesn't regress)

grails-shell-cli builds its own dependency management by parsing the published grails-bom POM, and previously skipped third-party imports such as spring-boot-dependencies (there was a test enforcing this). After this cleanup those versions only exist behind the Spring Boot import, so GrailsDependencyVersions now follows third-party imported BOMs too, with:

  • cycle/duplicate protection (spring-boot-dependencies is imported by both grails-bom and grails-base-bom),
  • first-writer-wins precedence so Grails' own pinned versions (e.g. Groovy 4.0.32) still win over Spring Boot's, and
  • per-POM ${...} property resolution (fixes a latent property-table clobbering bug during recursion).

The spec test that asserted third-party BOMs are never resolved was inverted; precedence, cycle-protection and nested-import coverage were added.

Verification

  • Regenerated the grails-bom and grails-base-bom POMs and diffed against baseline: only the removed constraints disappear; the spring-boot-dependencies import remains, so consumers still get the versions.
  • Resolved compile/runtime/test classpaths of representative modules (grails-data-mongodb-core, grails-codecs-core, grails-async-rxjava3, grails-converters, grails-web-core): every removed dependency resolves to Spring Boot's identical version.
  • ./gradlew validateDependencyVersions passes across all modules.
  • ./gradlew :grails-shell-cli:test passes (including the new GrailsDependencyVersionsSpec coverage).

Remove version pins from the root dependencies.gradle that duplicate
versions already managed by the spring-boot-dependencies BOM (Spring Boot
4.1.0). Where our pin equals Spring Boot's managed version it is dead
weight that only blocks free patch and security updates when Spring Boot
bumps the dependency, so it is removed and inherited from Spring Boot.

Removed (each equal to Spring Boot 4.1.0's managed version):
- byte-buddy 1.18.10 (and byte-buddy-agent)
- commons-codec 1.21.0
- commons-lang3 3.20.0
- jakarta.servlet-api 6.1.0
- jakarta.validation-api 3.1.1
- junit / junit-jupiter 6.0.3 (the 12 junit-* entries plus the redundant
  junit-bom platform import; Spring Boot already imports junit-bom:6.0.3)
- mongodb 5.8.0 (bson, mongodb-driver-core, mongodb-driver-sync,
  bson-record-codec)
- rxjava3 3.1.12

Also drop the jakarta.servlet/jakarta.validation excludes from
grails-bom/base/build.gradle. They only existed to win a since-resolved
selenium-versus-Spring-Boot conflict; both versions now match Spring
Boot, so its platform can manage them.

Kept intentionally: graphql-java 25.0 is retained as a deliberate drift
tripwire (graphql-java-extended-scalars is not managed by Spring Boot and
must move in lockstep), with a rationale comment added; groovy 4.0.32 and
selenium 4.38.0 remain intentionally divergent; spring-retry stays
because Spring Boot 4 dropped its management.

The legacy grails-shell-cli derives its own dependency management by
parsing the published grails-bom POM and previously skipped third-party
imports such as spring-boot-dependencies. Teach GrailsDependencyVersions
to also follow third-party imported BOMs, with cycle protection and
first-writer-wins precedence so Grails' own pinned versions still win, so
the CLI keeps surfacing the versions now inherited from Spring Boot.

Verified by regenerating the grails-bom and grails-base-bom POMs (only
the removed constraints disappear; the Spring Boot import remains),
confirming every affected module resolves the removed dependencies to
Spring Boot's identical versions, and running validateDependencyVersions
across all modules.

Fixes #15674

Assisted-by: claude-code:claude-opus-4-8
Copilot AI review requested due to automatic review settings June 11, 2026 15:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces redundant version pinning in grails-bom by removing constraints that exactly match Spring Boot 4.1.0’s managed versions, allowing Grails to automatically inherit future patch/security updates when Spring Boot bumps those dependencies. It also updates the legacy grails-shell-cli BOM parsing logic so that versions managed only behind third-party imported BOMs (notably spring-boot-dependencies) are still surfaced to the CLI.

Changes:

  • Removed dependencies.gradle pins/constraints that duplicate Spring Boot 4.1.0’s managed versions (e.g., byte-buddy, commons-codec/lang3, jakarta servlet/validation, junit, mongodb, rxjava3).
  • Updated GrailsDependencyVersions to recurse into third-party imported BOMs with cycle/duplicate protection, per-POM property resolution, and “first-writer-wins” precedence.
  • Updated/expanded grails-shell-cli specs to cover third-party BOM recursion, deduplication, and transitive BOM imports; removed no-longer-needed exclusions in the BOM Gradle build.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
grails-shell-cli/src/test/groovy/org/grails/cli/boot/GrailsDependencyVersionsSpec.groovy Updates tests to validate third-party BOM recursion, de-duplication, and transitive import handling.
grails-shell-cli/src/main/groovy/org/grails/cli/boot/GrailsDependencyVersions.groovy Implements recursive resolution of imported BOMs (including third-party) with precedence and cycle protection.
grails-bom/base/build.gradle Removes Jakarta excludes that were previously used for an older conflict and are now redundant.
dependencies.gradle Removes redundant BOM pins so versions inherit from Spring Boot 4.1.0; adds rationale comment for intentionally retained graphql-java “tripwire”.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jamesfredley

Copy link
Copy Markdown
Contributor Author

We need to figure out if selenium 4.38.0 should still be behind Spring Boot.

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.19048% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.4301%. Comparing base (7da662f) to head (6797b26).

Files with missing lines Patch % Lines
...rg/grails/cli/boot/GrailsDependencyVersions.groovy 76.1905% 1 Missing and 4 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##                8.0.x     #15730        +/-   ##
==================================================
- Coverage     48.4322%   48.4301%   -0.0021%     
- Complexity      15265      15267         +2     
==================================================
  Files            1875       1875                
  Lines           85852      85866        +14     
  Branches        14972      14976         +4     
==================================================
+ Hits            41580      41585         +5     
- Misses          37863      37865         +2     
- Partials         6409       6416         +7     
Files with missing lines Coverage Δ
...rg/grails/cli/boot/GrailsDependencyVersions.groovy 61.1111% <76.1905%> (+2.4904%) ⬆️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codeconsole

codeconsole commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Doe the spec have to hard code the spring bom version or can it resolve whatever the current one used is? 4.1.x?

@testlens-app

testlens-app Bot commented Jun 12, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 6797b26
▶️ Tests: 6400 executed
⚪️ Checks: 43/43 completed


Learn more about TestLens at testlens.app.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants