JaCoCo exclude in Maven and Gradle: packages, classes and generated code
The setups that work in Maven and Gradle, and five that look right but are not, measured with JaCoCo 0.8.16.

Write class-file paths, not package names: com/example/dto/**, not
com.example.dto.*. Then give the same list to the report and to the coverage
check. Most excludes that “don’t work” break one of those two rules.
Exclude patterns at a glance
| To exclude | Write |
|---|---|
| A package and its subpackages | com/example/dto/** |
| A package name anywhere | **/dto/** |
| A class and its nested classes | com/example/Application*.class |
| Classes by name | **/*Dto.class |
| Spring Boot’s main class | **/*Application*.class |
| One method | Annotate it @Generated |
| Lombok code | Nothing, since Lombok 1.18.34 |
* matches within one folder, ** across folders. The patterns match files
under target/classes or build/classes, so a nested class is its own file:
Application$Args.class. **/*Application*.class also matches any other class
with Application in its name.
We ran every setup here with JaCoCo 0.8.16, Maven 3.9.16 and Gradle 9.7.1 on JDK 26. The test project has five classes; two have tests. Without excludes, JaCoCo reports 8 of 25 lines (32%).

Exclude a package or class in Maven
Put <excludes> in the plugin’s own <configuration>, not inside one
<execution>. Then report and check both use it.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.16</version>
<configuration>
<excludes>
<exclude>com/example/dto/**</exclude>
<exclude>com/example/Application*.class</exclude>
</excludes>
</configuration>
<executions>
<execution><goals><goal>prepare-agent</goal></goals></execution>
<execution>
<id>report</id><phase>test</phase><goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
Result: two classes left, 8 of 10 lines.
Exclude a package or class in Gradle
Gradle has no excludes setting for the report. Filter the class folders the
task reads, on both jacocoTestReport and jacocoTestCoverageVerification.
Kotlin DSL, build.gradle.kts:
val coverageExcludes = listOf("com/example/dto/**", "com/example/Application*.class")
listOf(tasks.jacocoTestReport, tasks.jacocoTestCoverageVerification).forEach { task ->
task {
classDirectories.setFrom(
files(classDirectories.files.map { fileTree(it) { exclude(coverageExcludes) } })
)
}
}
Groovy DSL, build.gradle:
def coverageExcludes = ['com/example/dto/**', 'com/example/Application*.class']
[jacocoTestReport, jacocoTestCoverageVerification].each { task ->
task.classDirectories.setFrom(
files(task.classDirectories.files.collect { fileTree(it) { exclude coverageExcludes } })
)
}
Both gave the same result as Maven: two classes, 8 of 10 lines.
Why your JaCoCo exclude isn’t working
| What we tried | What happened |
|---|---|
com.example.dto.* (dots) | Nothing excluded |
com/example/dto (no /**) | Nothing excluded |
com/example/Application.class | Its nested class stayed, at 0 of 6 lines |
Maven: excludes in the report execution only, check at 80% | Report right, build failed: “lines covered ratio is 0.32” |
Gradle: excludes on jacocoTestReport only, verification at 80% | Same failure, same 0.32 |
Excludes on prepare-agent, or in Gradle’s test { jacoco { excludes } } | Every class still listed |

The last row catches many people. Those are the agent’s excludes. The classes are not instrumented, but the report still lists them, uncovered. Use them only for classes that fail under instrumentation.
Exclude generated code, Lombok and single methods
JaCoCo drops any class or method annotated with an annotation whose simple
name contains Generated, as long as it survives compilation (CLASS or
RUNTIME retention). A method we marked with our own @Generated vanished
from the report. JaCoCo has no other way to exclude a single method.
javax.annotation.processing.Generated, which many code generators add, is
discarded at compile time (SOURCE retention). A class carrying it stayed in
the report. Exclude generated classes by path instead.
Lombok has marked everything it generates @lombok.Generated since 1.18.34.
With Lombok 1.18.48, our @Data class was gone from the report with no
lombok.config. On older Lombok, add
lombok.addLombokGeneratedAnnotation = true to lombok.config.
Exclude the same files in SonarQube
SonarQube reads JaCoCo’s XML report, but counts files missing from it as
uncovered. List the same files, as source paths, in
sonar.coverage.exclusions. See
JaCoCo vs SonarQube coverage.
What Supercov adds
npx supercov -- mvn test
npx supercov runs latest gaps
Supercov measures source files, not class files, so JaCoCo’s excludes and
@Generated don’t apply to it. You name the directories that hold your own
code. It records which test covered each line, with branches and MC/DC. On
this project it showed that no test tried a large order from a non-member.
For tools beyond JaCoCo, see Java code coverage.