You import spring-boot-dependencies as a BOM (scope=import) instead of using spring-boot-starter-parent. How do you override a managed version now, and why is it different?
answer
- Imported BOM => property override does NOT work
- Add own dependencyManagement entry BEFORE the Boot import
- Imported BOMs: first-declared-wins
- Explicit <version> in <dependencies> always overrides
- Import the newer inner BOM (jackson-bom) first
basics
~10 sProperty overrides no longer work. Add your own <dependencyManagement> entry with the desired version, declared BEFORE the imported spring-boot-dependencies BOM. Maven's 'first declaration wins' for imported BOMs makes your entry take precedence.
solid answer
~40 sWith the parent, versions are properties you can redefine. But when you import spring-boot-dependencies as a BOM (<scope>import</scope>), you can't override those versions with properties — the properties are resolved inside the imported POM, not your project. Instead you add an explicit <dependencyManagement> entry for the artifact with the version you want, and place it **before** the spring-boot-dependencies import. Maven resolves dependency management using nearest/first-declared-wins among imported BOMs and local management, so a management entry in your own POM (or an earlier import) beats the imported Boot BOM. You can also just declare an explicit <version> on the dependency in <dependencies>, which always overrides managed versions. Either way you've stepped off the tested set.
code
xml · 19 lines<dependencyManagement>
<dependencies>
<!-- Override wins because it's declared first -->
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.18.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.3.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>go deeper
Know that there are two ways to consume Boot's versions: parent (inherit) vs BOM (import).
Know that with imported BOM you override via your own dependencyManagement placed before the Boot import, because property override no longer applies.
Explain Maven's first-declared-wins for imported BOMs and when to import an inner BOM vs pin a single artifact.
Standardize consumption model across many services (parent vs import) and codify override placement/ordering to avoid silent version regressions.
## Two ways to consume Spring Boot's dependency management 1. **Inherit** from `spring-boot-starter-parent` (real Maven parent). Managed versions are properties you can redefine in your child `<properties>`. 2. **Import** `spring-boot-dependencies` as a BOM: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.3.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` Teams import when they already have a corporate parent POM and can only inherit from one parent. ## Why property override stops working Maven property resolution for an **imported** BOM happens in the context of *that* POM, at import time. Redefining `<jackson-bom.version>` in *your* `<properties>` does not reach inside spring-boot-dependencies, so the imported management entries keep resolving to Boot's value. This is an explicit caveat in the Spring Boot reference documentation. ## The correct override for imported BOMs Add your own `<dependencyManagement>` entry and put it **before** the Boot import. For an artifact managed by an inner BOM (like Jackson), import the newer BOM first: ```xml <dependencyManagement> <dependencies> <!-- MUST come first so it wins --> <dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>jackson-bom</artifactId> <version>2.18.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.3.2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` For a single artifact you can instead list an explicit management entry: ```xml <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.13</version> </dependency> ``` ## Ordering rule Among imported BOMs, Maven uses **first-declared-wins** for a given managed artifact. So the override BOM/entry must precede spring-boot-dependencies. A dependency-management entry declared directly in your POM also outranks imported BOMs. ## The blunt hammer: explicit <version> on the dependency Declaring `<version>` directly in `<dependencies>` (not `<dependencyManagement>`) always overrides any managed version — with parent or imported BOM alike. It's the simplest override but only affects that one artifact and bypasses the coordinated BOM, so related modules can drift out of sync. ## Trade-off All of these move you off the exact set Boot tested. Prefer the smallest, most surgical override and document why (e.g. CVE fix).
- Why must the override entry come before the spring-boot-dependencies import?For an imported BOM, Maven resolves a managed artifact's version to the FIRST matching declaration it encounters. If Boot's BOM is declared first, its version wins; putting your override first makes yours win.
- Does an explicit <version> in the <dependencies> section behave differently from a <dependencyManagement> entry?Yes. A direct <version> in <dependencies> unconditionally sets that one artifact's version and beats all management. A <dependencyManagement> entry only supplies a default and interacts with import ordering, but can steer a whole inner BOM.
saying these in an interview costs you the question
- Claiming property override works the same for imported BOM as for parent
- Putting the override AFTER spring-boot-dependencies and expecting it to win
- Thinking last-declared-wins for imported BOMs (it's first-wins)
- Not realizing you can only inherit one Maven parent, which is why teams import