What is the difference between the makeBom and makeAggregateBom goals?
answer
- makeBom = per module
- makeAggregateBom = whole reactor
- own modules become internal components
- one SBOM per deployable
- bind aggregate in parent
basics
~10 smakeBom 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 sBoth 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# whole-product SBOM from the reactor root
mvn package org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBomgo deeper
Knows both goals exist and produce a BOM file.
Picks makeAggregateBom for multi-module apps, makeBom for single libraries.
Explains the per-module-duplication gotcha and how aggregate models internal modules.
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