Aligning Multi-Module Dependency Versions with Maven BOM Imports
Learn how to use Maven Bill of Materials (BOM) imports to centralize dependency versions across multi-module projects and eliminate version drift.
30 Jun 2026, 08:50 UTC

The Problem: Version Drift in Multi-Module Projects
In large Maven projects, managing dependency versions across dozens of modules often leads to "version drift," where different modules accidentally use different versions of the same library. This results in NoSuchMethodError or ClassNotFoundException at runtime because the classpath contains conflicting versions of a JAR.
The solution is to use a Bill of Materials (BOM). A BOM is a special POM file that centralizes dependency versions in a <dependencyManagement> section. By importing a BOM, you ensure every module in your project uses a curated, compatible set of versions without having to manually synchronize version strings across multiple files.
How BOM Import Works
A BOM is not a library; it is a configuration manifest. To use it, you import it into your parent POM using the import scope. This tells Maven to treat the versions defined in the BOM as if they were defined in your own <dependencyManagement> section.
Worked Configuration Example
Assume you are using a technology stack like Spring Boot. Instead of defining versions for every Spring starter, you import the Spring Boot Dependencies BOM.
Parent POM Configuration:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>project-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<!-- Import the BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Child Module POM:
In the child module, you declare the dependency without a version tag. Maven will resolve the version from the imported BOM.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId;
<!-- No version specified here -->
</dependency>
</dependencies>
Engineering Limits and Common Mistakes
While BOMs simplify versioning, there are specific Maven behaviors that can lead to configuration errors:
- Incorrect Scope Placement: The
<scope>import</scope>is only valid inside the<dependencyManagement>block. If you place a BOM import inside the standard<dependencies>block, Maven will attempt to download it as a standard JAR, and the build will fail because the BOM is a POM file. - Explicit Version Overrides: If a child module defines an explicit version for a dependency, that version always wins over the BOM version. This can silently reintroduce version drift if developers add versions to child POMs for "quick fixes."
- BOM Ordering Conflicts: If you import multiple BOMs that define the same dependency, the first BOM declared in the list takes precedence. The order of imports in the parent POM determines the final resolved version.
- Plugin Management: BOMs only manage dependencies. They do not manage Maven plugin versions. You must still use the
<pluginManagement>section to centralize plugin versions.
Verifying the Resolution
To ensure the BOM is working and your modules are inheriting the correct versions, use the following diagnostic steps. Run these commands from the terminal in the root of your project.
1. Inspect the Effective POM
Run the following command to see the fully merged POM after all imports are processed:
mvn help:effective-pom
Search the output for the <dependencyManagement> section. You should see the versions from the BOM explicitly listed as if you had typed them manually.
2. Check the Dependency Tree
To verify the actual version being packaged into a specific module, run:
mvn dependency:tree
Check the version number next to the artifact. If it matches the BOM version and you have no version tag in the child POM, the import is successful.
3. Test for Version Drift
Remove the version tag from a dependency in a child module. If the build fails with a "version missing" error, the BOM is either not imported correctly or the artifact is not defined within that specific BOM.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.