Maven BOM
last modified June 12, 2025
In this tutorial, we will explore how to use Maven BOM (Bill of Materials) to efficiently manage dependency versions across multiple projects. By leveraging BOMs, developers can ensure consistency, avoid version conflicts, and simplify dependency management in complex applications.
A Maven BOM (Bill of Materials) is a specialized POM (Project Object Model) file that acts as a central reference for dependency versions. Instead of manually specifying versions for each dependency across different modules or projects, a BOM allows you to define them once and reuse them wherever needed.
This approach is especially beneficial for large-scale applications with numerous modules that share common dependencies. Without a BOM, version mismatches can lead to compatibility issues, making upgrades and maintenance challenging.
A BOM simplifies dependency management by providing a single source of truth for dependency versions. It allows developers to import a predefined set of dependencies and their versions into their projects, ensuring that all modules and projects use the same versions of shared dependencies. This reduces the risk of version conflicts and makes it easier to manage updates across multiple projects.
BOM has several advantages, including:
- Consistency Across Projects: Ensures that all modules and projects use the same versions of shared dependencies.
- Simplified Version Management: Eliminates the need to manually specify versions in each project's POM file.
- Easier Upgrades: Updating the BOM automatically propagates the new versions to all projects that import it.
- Reduced Version Conflicts: Helps prevent dependency mismatches that can lead to runtime errors or build failures.
Creating a BOM Project
To create a BOM project, you need to define a POM file with the packaging type
set to pom
. This POM will contain the dependency management section
where you can specify the versions of the dependencies you want to manage.
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>example-bom</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.2.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>jackson-bom</artifactId> <version>2.16.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>common-lib</artifactId> <version>2.5.0</version> </dependency> </dependencies> </dependencyManagement> </project>
In this example, we define a BOM project with the following elements:
-
<groupId>
: The group ID of the BOM project, which uniquely identifies it. -
<artifactId>
: The artifact ID of the BOM project, which is used to reference it in other projects. -
<version>
: The version of the BOM project. -
<packaging>
: The packaging type, which must be set topom
for a BOM project.
The <dependencyManagement>
section contains a list of
dependencies with their versions. These dependencies can be imported into other
projects that use this BOM. The import
scope is used for
dependencies that are meant to be used as a BOM, allowing other projects to
inherit the versions defined in this BOM without needing to specify them
explicitly.
You can add any dependencies you want to manage in the BOM. In this example,
we include the Spring Boot BOM, the Jackson BOM, and a custom library called
common-lib
. The versions of these dependencies are defined in the
BOM, allowing other projects to use them without specifying the versions
explicitly.
Using the BOM in Other Projects
To use the BOM in other Maven projects, you need to import it in the
dependencyManagement
section of the project's POM file. This allows
you to inherit the versions defined in the BOM without specifying them
explicitly in each project's POM. Here is an example of how to do this:
<dependencyManagement> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-bom</artifactId> <version>1.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- Version inherited from BOM --> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>common-lib</artifactId> <!-- Version inherited from BOM --> </dependency> </dependencies>
The dependencyManagement
section allows you to import the BOM,
which defines versions for all dependencies listed within it. When you declare
dependencies in your project, you do not need to specify their versions, as
they are inherited from the BOM.
This approach simplifies version management, as you can update the BOM in one place, and all projects using it will automatically use the updated versions. It also helps avoid version conflicts and ensures that all projects use the same versions of shared dependencies.
Inheriting from Parent BOM
You can also create a BOM that inherits from another BOM, allowing you to extend or override versions as needed. This is useful for creating a custom BOM that builds upon an existing BOM, such as the Spring Boot BOM.
<project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.example</groupId> <artifactId>example-bom</artifactId> <version>1.0.0</version> </parent> <artifactId>my-project</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
In this example, the project inherits from the example-bom
, which
contains the Spring Boot BOM. This allows you to use the versions defined in
the BOM without explicitly declaring them in your project POM.
Multi-Module Project with BOM
In a multi-module Maven project, you can create a parent POM that includes the BOM and manages dependencies for all child modules. This allows you to maintain consistent dependency versions across all modules in the project.
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>parent-project</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <module>bom</module> <module>service</module> <module>web</module> </modules> <dependencyManagement> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-bom</artifactId> <version>${project.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
In this parent POM, we define a dependencyManagement
section that
imports the BOM. Each child module can then declare its dependencies without
specifying versions, as they will inherit the versions defined in the BOM.
Overriding BOM Versions
You can override specific versions from the BOM when needed. This is useful when you want to use a different version of a dependency than the one defined in the BOM, while still benefiting from the BOM's version management for other dependencies.
<dependencyManagement> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>example-bom</artifactId> <version>1.0.0</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Override specific version --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> </dependencies> </dependencyManagement>
In this example, we import the example-bom
but override the version
of jackson-databind
to 2.15.2
. This allows us to use a
different version of this dependency while still benefiting from the other
versions defined in the BOM.
Popular Public BOMs
Many popular libraries and frameworks provide their own BOMs to simplify dependency management. These BOMs define a set of recommended versions for dependencies commonly used together, making it easier to manage versions in your projects.
<dependencyManagement> <dependencies> <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>
The Spring Boot BOM provides a set of managed dependencies for Spring Boot applications, ensuring that all dependencies are compatible with each other.
<dependencyManagement> <dependencies> <dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>jackson-bom</artifactId> <version>2.16.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
The Jackson BOM provides a set of managed dependencies for the Jackson JSON processing library, ensuring that all Jackson components are compatible with each other.
BOM Best Practices
- Single Responsibility: Each BOM should manage a logical group of related dependencies
- Clear Versioning: Use semantic versioning for your BOMs
- Documentation: Document the purpose and contents of each BOM
- Testing: Test BOM updates with all consuming projects
- Minimal Overrides: Avoid overriding BOM versions unless necessary
Source
In this article we have explored how to use Maven BOMs to manage dependency versions across multiple projects.
Author
List all Java tutorials.