skip to content

What is the difference between the makeBom and makeAggregateBom goals?

level: middleimportance: must knowfreq 45%

answer

  1. makeBom = per module
  2. makeAggregateBom = whole reactor
  3. own modules become internal components
  4. one SBOM per deployable
  5. bind aggregate in parent

basics

~10 s

makeBom produces one SBOM per module from that module's dependencies. makeAggregateBom runs once for a multi-module (reactor) build and produces a single SBOM covering all modules together.

solid answer

~40 s

Both goals come from the cyclonedx-maven-plugin. `makeBom` generates an SBOM scoped to a single module — if you put it in a multi-module build it runs in each module and produces N separate BOMs. `makeAggregateBom` is designed for reactor builds: it runs at the top and produces one consolidated SBOM that includes the components of every module, while treating the project's own modules as internal components rather than third-party dependencies. For a typical application you want `makeAggregateBom` so consumers get a single artifact describing the whole deliverable. Use `makeBom` for a standalone library, or when you genuinely want per-module BOMs. A common gotcha: binding `makeBom` in a parent POM can cause duplicate/empty BOMs in aggregator modules — aggregate avoids that.

code

bash · 2 lines
bash
# whole-product SBOM from the reactor root
mvn package org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom

go deeper

for a junior

Knows both goals exist and produce a BOM file.

for a middle

Picks makeAggregateBom for multi-module apps, makeBom for single libraries.

for a senior

Explains the per-module-duplication gotcha and how aggregate models internal modules.

for a principal

Standardizes one-SBOM-per-deployable across the org and wires it into the release pipeline.

## The two goals A **multi-module Maven build** (a 'reactor') has a parent/aggregator POM that lists `<modules>`, and each child module produces its own artifact. The question is: do you want one SBOM for the whole thing, or one per module? ### `makeBom` - Operates on **a single module's** resolved dependencies. - If bound in a parent that all modules inherit, it executes **once per module**, producing several independent `bom.xml` files. - Best for a **single-artifact project** (e.g., a library) or when downstream tooling specifically wants per-module BOMs. ### `makeAggregateBom` - Designed for **reactor builds**. It runs and produces **one consolidated SBOM** describing all modules and their combined dependency set. - It recognizes the reactor's own modules and represents them as **components of the project** rather than external third-party dependencies — so the BOM reflects 'this is my app, and here are its sibling modules plus everything they pull in'. - Best for **deployable applications** where a single, whole-product SBOM is the deliverable. ## Why it matters Vulnerability scanners and compliance systems usually expect one SBOM per deployable unit. Shipping a single aggregate BOM avoids the confusion of merging N partial BOMs and prevents double-counting shared dependencies. ## Typical configuration Put the aggregate execution in the **aggregator/parent POM**: ```xml <plugin> <groupId>org.cyclonedx</groupId> <artifactId>cyclonedx-maven-plugin</artifactId> <version>2.8.0</version> <executions> <execution> <id>aggregate-bom</id> <phase>package</phase> <goals><goal>makeAggregateBom</goal></goals> </execution> </executions> </plugin> ``` ## Gotchas - Don't bind both goals; pick one strategy. - `makeAggregateBom` needs the reactor to be built together (`mvn package` at the root), not module-by-module, to see all modules. - For a single-module project the two are effectively equivalent; `makeBom` is the simpler choice there.

  • In a multi-module build, what happens if you bind makeBom in the parent?
    It inherits to every module and runs once per module, producing several separate BOM files instead of one consolidated one.
  • How does makeAggregateBom treat the reactor's own modules?
    It represents them as internal components of the project rather than as external third-party dependencies, then includes their combined dependency set.

saying these in an interview costs you the question

  • Claiming makeAggregateBom merges several pre-generated BOMs (it builds one from the reactor's resolved graph)
  • Using makeBom on the parent and expecting a single whole-product SBOM
  • Running modules individually and expecting aggregate to see all of them

context