skip to content

In a Maven project that uses spring-boot-starter-parent, how do you override the version of a dependency that Spring Boot manages for you?

level: juniorimportance: must knowfreq 55%

answer

  1. Redefine the property, not the <version>
  2. jackson-bom.version, spring-framework.version, slf4j.version
  3. Child <properties> overrides parent
  4. Only works with the PARENT, not imported BOM
  5. Property names live in spring-boot-dependencies POM

basics

~10 s

Redefine the version property in your own <properties> block. Spring Boot's parent POM sets properties like jackson-bom.version; declaring the same property in your pom.xml overrides the managed version everywhere it's used.

solid answer

~40 s

Spring Boot manages versions through spring-boot-dependencies (imported by spring-boot-starter-parent). Every managed version is expressed as a Maven property, e.g. <jackson-bom.version>, <slf4j.version>, <spring-framework.version>. To override one, redefine that exact property in your project's <properties> block; because Maven properties in the child POM win, your value is used for that dependency and all transitive uses of the same property. You don't declare a <version> on the dependency itself — the starters stay version-less and the property drives everything. Find the property names in the spring-boot-dependencies POM. This is the recommended override path when you use the parent, but overriding still risks stepping outside the combination Spring Boot tested.

code

xml · 19 lines
xml
<!-- pom.xml using spring-boot-starter-parent -->
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.3.2</version>
</parent>

<properties>
  <!-- Override just this managed version -->
  <jackson-bom.version>2.18.1</jackson-bom.version>
</properties>

<dependencies>
  <!-- No <version> here: it's managed -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
  </dependency>
</dependencies>

go deeper

for a junior

Know that starters are version-less because Boot manages versions, and that you override by redefining the version property in your own <properties>.

for a middle

Know the real property names (jackson-bom.version, spring-framework.version) and that a property drives a whole BOM's artifacts together.

for a senior

Contrast parent (property override works) vs imported BOM (property override does NOT work). Weigh drift from the tested set.

for a principal

Set org policy on where/when overrides are allowed, how they're tracked, and how CVE-driven bumps are validated against Boot's tested set.

## What 'managed version' means Spring Boot ships a curated dependency set. `spring-boot-starter-parent` inherits from `spring-boot-dependencies`, a POM whose `<dependencyManagement>` section pins a specific version for hundreds of libraries (Jackson, SLF4J, Hibernate, Netty, Reactor, the Spring Framework itself, etc.). Because of dependency management, when you declare `spring-boot-starter-web` **without a `<version>`**, Maven fills in the tested version. This is why starter dependencies in your `pom.xml` have no version tag. ## How versions are expressed — properties Inside `spring-boot-dependencies`, each managed version is not hard-coded on the dependency; it is a **Maven property**. For example the POM contains `<jackson-bom.version>2.17.x</jackson-bom.version>` and then references `${jackson-bom.version}`. Real property names include `spring-framework.version`, `jackson-bom.version`, `slf4j.version`, `hibernate.version`, `netty.version`, `reactor-bom.version`. ## Overriding via a property (the parent case) Because a child POM's properties override an inherited parent's properties, you override a managed version by **redeclaring the same property** in your own `<properties>`: ```xml <properties> <jackson-bom.version>2.18.1</jackson-bom.version> </properties> ``` Maven now substitutes your value wherever `${jackson-bom.version}` appears in the managed dependency section. You do **not** add a `<version>` to the dependency element. This keeps the whole Jackson BOM consistent instead of only bumping one artifact. ## Finding property names Open the `spring-boot-dependencies` POM for your Boot version (it's in your local `~/.m2` or on Maven Central) and search its `<properties>` section, or read the 'Dependency Versions' appendix in the Spring Boot reference docs. Guessing property names is a common mistake — `jackson.version` is wrong; it is `jackson-bom.version`. ## Important limitation Property-based override works **only when you use `spring-boot-starter-parent`** (real inheritance). If you instead **import** `spring-boot-dependencies` as a BOM (`<scope>import</scope>`), redefining the property does *not* take effect — you must override through your own `<dependencyManagement>` entry placed before the imported BOM. (That is a separate, more advanced question.) ## Why care Each Boot release is designed and tested against one specific dependency combination. Overriding is legitimate (a security CVE fix, a needed bugfix) but moves you off the tested set, so do it deliberately and minimally.

  • Where do you find the exact property name to override?
    In the spring-boot-dependencies POM for your Boot version (its <properties> section), or the 'Dependency Versions' appendix in the Spring Boot reference docs. Don't guess — e.g. it's jackson-bom.version, not jackson.version.
  • Does redefining the property also affect transitive dependencies that use it?
    Yes. The property drives the managed version for every artifact declared with ${that.property}, so a whole BOM (e.g. all Jackson modules) moves together, keeping them consistent.

saying these in an interview costs you the question

  • Thinking you must add <version> to the starter/dependency to change it
  • Guessing property names like 'jackson.version' instead of 'jackson-bom.version'
  • Believing property override works when the BOM is imported (it only works with the parent)
  • Assuming overriding is free of risk / fully supported

context