skip to content

What is a Maven BOM, and how do you author one?

level: middleimportance: must knowfreq 70%

answer

  1. packaging=pom, no code
  2. dependencyManagement = version catalog
  3. import scope + type pom
  4. consumer omits version
  5. spring-boot-dependencies

basics

~10 s

A BOM (Bill of Materials) is a POM-packaged artifact whose only job is a <dependencyManagement> block listing curated versions. Consumers import it so they can add those dependencies without specifying versions.

solid answer

~30 s

A BOM is an artifact with `<packaging>pom</packaging>` that contains a `<dependencyManagement>` section pinning versions (and sometimes scopes/exclusions) for a set of related libraries. It ships no code — it is a published version catalog. You author it as a standalone module (its own groupId/artifactId/version) declaring managed dependencies. Downstream projects pull it in with `<scope>import</scope>` and `<type>pom</type>` inside their own `<dependencyManagement>`, then declare those dependencies version-free. This centralizes version decisions, guarantees compatible sets (e.g. Spring Boot, Jackson modules), and lets you bump one BOM version to upgrade everything coherently. Well-known examples: spring-boot-dependencies, jackson-bom.

code

xml · 15 lines
xml
<project>
  <groupId>com.acme</groupId>
  <artifactId>acme-bom</artifactId>
  <version>1.4.0</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.acme</groupId>
        <artifactId>acme-core</artifactId>
        <version>1.4.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

go deeper

for a junior

Know a BOM is a versions-only POM and consumers omit the version.

for a middle

Author one with packaging=pom + dependencyManagement; know import scope mechanics.

for a senior

Curate compatible sets, version the BOM independently, document upgrade policy.

for a principal

Govern org-wide version policy via BOMs; decide BOM granularity and ownership.

## What a BOM is A **BOM (Bill of Materials)** is a special Maven artifact whose sole purpose is to declare a curated, internally-consistent set of dependency **versions**. It contains no Java code and produces no JAR — it is published as a POM file only. Think of it as a published, versioned price-list of "if you use library X, use exactly this version." ## How it is built Two things define a BOM: 1. `<packaging>pom</packaging>` — tells Maven this artifact is just a POM, no compiled output. 2. A `<dependencyManagement>` block — this section **declares** versions but does **not** add dependencies to anyone's classpath. It only takes effect when a dependency with the same groupId+artifactId is actually declared. ```xml <project> <groupId>com.acme</groupId> <artifactId>acme-bom</artifactId> <version>1.4.0</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>com.acme</groupId> <artifactId>acme-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>com.acme</groupId> <artifactId>acme-web</artifactId> <version>1.4.0</version> </dependency> </dependencies> </dependencyManagement> </project> ``` ## How consumers use it A downstream project imports the BOM **inside its own `<dependencyManagement>`** using `<scope>import</scope>` and `<type>pom</type>`: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>com.acme</groupId> <artifactId>acme-bom</artifactId> <version>1.4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` Then the consumer declares the actual dependency **without a `<version>`** — the BOM supplies it: ```xml <dependencies> <dependency> <groupId>com.acme</groupId> <artifactId>acme-core</artifactId> </dependency> </dependencies> ``` ## Why it matters - **Single source of version truth** — bump the BOM version once, every consumer upgrades coherently. - **Compatibility guarantee** — the publisher has tested that all listed versions work together (e.g. all Jackson modules at the same minor). - **Decouples version policy from usage** — teams declare *what* they need, not *which version*. Real-world BOMs: `spring-boot-dependencies`, `spring-cloud-dependencies`, `jackson-bom`, `junit-bom`.

  • Does <dependencyManagement> add a dependency to the classpath?
    No. It only declares versions/scopes/exclusions. The dependency must still be declared in <dependencies> for it to be on the classpath.
  • What packaging must a BOM use?
    pom — it ships only a POM file, no JAR.

A BOM is like a restaurant's tasting menu: it lists exact dishes that pair well together. You don't pick portions — you just say 'I'll have the menu' and everything is pre-matched.

saying these in an interview costs you the question

  • Saying a BOM puts dependencies on the classpath (it only manages versions).
  • Confusing a BOM with a fat/uber JAR.
  • Thinking the BOM must be a parent of the consumer.

context