Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To configure JaCoCo across a Maven multi-module build, attach its agent to the test JVMs in the modules that run tests, then choose between a report for each module and a reactor-wide report-aggregate. For one combined report, run the aggregate goal in a project that declares dependencies on the modules whose coverage should appear; dependency scope determines whether a module contributes source and classes as well as execution data.

How JaCoCo fits into a multi-module build

JaCoCo’s Maven plug-in supplies the runtime agent to tests and creates coverage reports. Its documented Maven-runtime prerequisites are Maven 3.0 or newer and Java 1.8 or newer; the test executor can run on Java 1.5 or newer. Choose and pin a released plug-in version compatible with your build, and consult the goal documentation matching that version. The JaCoCo trunk documentation currently labels its version 0.8.16-SNAPSHOT, which is a snapshot rather than a released version.

The prepare-agent goal runs in the initialize phase by default. It sets a Maven property—normally argLine—to the JVM argument that loads JaCoCo’s Java agent. Surefire or Failsafe must pass that argument to a forked test JVM. Coverage data is written when the instrumented process terminates by default.

Configure the agent for unit tests

In a conventional reactor, configure the JaCoCo plug-in in the parent POM’s build/plugins so child modules inherit it. Use a released version appropriate to the project; the version below is illustrative, not a recommendation to use a particular release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<build>
  <plugins>
    <plugin>
      <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
      <version>REPLACE_WITH_PINNED_RELEASE></version>
      <executions>
        <execution>
          <goals>
            <goal>prepare-agent</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

JaCoCo’s default lifecycle binding already attaches prepare-agent to initialize; an explicit execution like the one above makes the inherited setup visible in the POM. If Surefire sets its own JVM arguments, preserve JaCoCo’s generated property using late evaluation, for example:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>@{argLine} -your -extra -arguments</argLine>
  </configuration>
</plugin>

Replace the example extra arguments with the actual JVM options your tests need. Overwriting argLine without retaining JaCoCo’s value prevents the agent from being passed to the test process.

Make sure tests run in a forked JVM

  • Do not configure Surefire or Failsafe with forkCount set to 0 or forkMode set to never. In those modes, tests do not run in a JVM launched with JaCoCo’s javaagent, so coverage is not recorded.
  • If reports need line-number details or source highlighting, compile target classes with debug information.
  • Run the Maven lifecycle through verify when relying on JaCoCo’s default report or check phase bindings.

Choose module reports or one aggregate report

Approach Coverage scope When to use it Default output or input
report One Maven project Each module needs its own report. Reads ${project.build.directory}/jacoco.exec by default; the goal binds to verify.
report-aggregate Dependent projects in the Maven reactor, plus execution data from the reporting project itself A combined view is needed, including cases where integration tests in one project exercise code in another. Writes HTML, XML, and CSV under ${project.reporting.outputDirectory}/jacoco-aggregate by default.

Configure the aggregate-report project

Run report-aggregate in a reporting project that declares dependencies on the reactor projects whose coverage belongs in the report. This report project must be able to resolve those dependencies, and the relevant modules must be included in the Maven invocation. A Maven aggregator POM is not automatically a suitable aggregate-report project just because it lists modules: configure the dependencies that JaCoCo uses to collect project data.

For example, a dedicated reporting module can declare production modules with scopes that include their sources and classes, and a test-only module with test scope when its execution data should count without adding that test module’s sources to the report:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<dependencies>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>service-a</artifactId>
    <version>${project.version}</version>
  </dependency>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>integration-tests</artifactId>
    <version>${project.version}</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Add the JaCoCo report-aggregate goal to an execution in that reporting project. Its default lifecycle binding is verify; invoking mvn verify from the reactor root runs the lifecycle for included modules. The aggregate goal has existed since JaCoCo 0.7.7. Its includeCurrentProject parameter was added in 0.8.9 and defaults to false.

Dependency scope controls report contents

Dependency scope in the reporting project What JaCoCo includes
compile, runtime, or provided The project’s source and execution data are included.
test Execution data is included, but the project’s sources and classes are not added to the report.

This distinction is useful when a test-only module runs tests against production modules: its execution data can contribute coverage of production code without making test-module code part of the report.

Keep unit-test and integration-test coverage separate

Use prepare-agent-integration for a distinct integration-test pass. It binds to pre-integration-test and writes to ${project.build.directory}/jacoco-it.exec by default. Pair it with report-integration, which reads that file and binds to verify by default.

Configure the integration-test runner to receive the integration agent argument, while preserving any other JVM options it needs. Make sure the lifecycle allows the integration tests to finish before the report goal runs. JaCoCo documents separate unit-test and integration-test reports; the default execution-data files are jacoco.exec and jacoco-it.exec, respectively.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Diagnose missing modules or empty reports

  • A module has no coverage: confirm tests ran in a forked Surefire or Failsafe JVM and that the runner retained JaCoCo’s agent argument.
  • A module’s sources are absent from an aggregate: check that the reporting project declares it as a dependency and that its scope is compile, runtime, or provided. With test scope, only execution data is added.
  • The expected reactor project is not collected: confirm the aggregate-report project resolves it as a dependency and the module is included in the Maven invocation.
  • The expected execution-data file is absent: check whether the relevant tests ran to completion and whether the configured agent destination matches the report goal’s input. The aggregate goal considers *.exec files in target directories by default.
  • Data files or classes are unexpectedly excluded: inspect the aggregate goal’s execution-data and class-file include/exclude settings. Its wildcard include/exclude parameters exclude nothing by default.

JaCoCo’s report-goal class exclusions control what appears in the report; they do not disable the agent or change which tests run.

Make coverage limits fail the build

Use JaCoCo’s check goal when coverage rules should gate a build. Rules can target bundles, packages, classes, source files, or methods. Supported counters include instructions, lines, branches, complexity, methods, and classes; limits can use covered or missed ratios.

Ratio limits range from 0.0 to 1.0. Configure thresholds against a scope whose classes and execution data you understand; an aggregate percentage is not meaningful if intended modules or test runs are missing. haltOnFailure defaults to true, so a violated rule can fail the build. The number-of-decimal-places setting controls displayed precision.

Handle Maven Site reports deliberately

When using JaCoCo with Maven Site Plugin, explicitly select report sets where appropriate. The JaCoCo Maven documentation warns that leaving reports unselected can produce redundant aggregate reports.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.