skip to content

What is the difference between the dependency-check `check` and `aggregate` goals in a multi-module Maven build?

level: middleimportance: should knowfreq 40%

answer

  1. check = per module, N reports
  2. aggregate = whole reactor, 1 report
  3. aggregate runs on parent/root
  4. single gate vs per-module gate
  5. avoid scanning twice

basics

~10 s

check scans each module on its own and produces a report per module. aggregate scans the whole multi-module project together and produces a single combined report at the root.

solid answer

~40 s

Both goals scan dependencies for CVEs, but they differ in scope for a reactor (multi-module) build. `dependency-check:check` runs per-module: each module evidences and reports only its own dependencies, giving you N reports. `dependency-check:aggregate` is meant to run on the root/parent and collects the dependencies of all child modules into one consolidated report. Use `aggregate` when you want a single project-wide view and a single pass/fail gate, which is usually what teams want in CI. Use `check` when you care about per-module ownership or want each module to fail independently. A common setup binds `aggregate` at the aggregator POM and skips `check` in children to avoid duplicate scanning and redundant NVD work.

code

bash · 4 lines
bash
# One consolidated report for the whole multi-module project
mvn org.owasp:dependency-check-maven:aggregate
# vs. per-module scan during a normal verify
mvn verify   # if 'check' is bound in each module

go deeper

for a junior

Know check is per module and aggregate is whole-project.

for a middle

Know aggregate belongs on the parent and gives one report and one gate.

for a senior

Weigh per-module ownership and independent failure vs. a single repo-wide gate and faster de-duplicated scans.

for a principal

Standardize the choice across the org and embed it in a shared parent POM so every repo gets consistent scanning behavior.

## Reactor builds recap A **multi-module** (reactor) Maven project has an aggregator/parent POM with `<modules>` listing child modules. When you build the root, Maven builds all children in dependency order. Vulnerability scanning has to decide: scan each module separately, or scan the whole thing as one? ## `check` — per module `dependency-check:check` executes inside each module. Each module: - resolves its own dependency graph, - matches CVEs, - writes its own report (e.g. `module-a/target/dependency-check-report.html`), - applies `failBuildOnCVSS` to its own findings. Result: N reports, N independent gates. Good for clear per-team ownership, but noisy and slower (each module may redo NVD work and re-scan shared dependencies). ## `aggregate` — whole project `dependency-check:aggregate` is designed to run on the **aggregator** POM. It walks all the child modules' dependencies and produces **one** consolidated report at the root, with a single pass/fail decision. This is usually what you want for a repository-level CI gate: one report to read, one threshold to enforce. ## Typical configuration Bind `aggregate` at the parent and avoid binding `check` in children so you do not scan twice: ```xml <!-- parent / aggregator pom.xml --> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>9.2.0</version> <executions> <execution> <goals><goal>aggregate</goal></goals> </execution> </executions> </plugin> ``` ## Choosing - One repo, one team, one gate: **aggregate**. - Independent modules with separate release cadence/ownership: **check** per module. - Avoid binding both for the same dependencies — it duplicates effort and can produce conflicting gates.

  • Why might aggregate be faster than check across many modules?
    It de-duplicates shared dependencies and does the NVD matching once for the whole reactor instead of repeating work in every module.
  • Where does the aggregate report get written?
    At the aggregator (root) module's target directory, since it runs on the parent that owns all the modules.

saying these in an interview costs you the question

  • Saying aggregate scans only the parent POM's own dependencies — it pulls in the children's dependencies too.
  • Binding both check and aggregate on the same dependencies, causing duplicate scans and confusing dual gates.

context