How would you use bannedDependencies and banDuplicateClasses to protect a build?
answer
- pattern g:a:v:type:scope with *
- includes carve exceptions from excludes
- banDuplicateClasses = same FQCN in 2 jars
- jar hell / classpath order
- ignoreClasses + findAllDuplicates
basics
~20 sbannedDependencies fails the build if a forbidden artifact appears (e.g. an old logging lib or a vulnerable version), using groupId:artifactId:version patterns with wildcards. banDuplicateClasses fails when the same class exists in two jars on the classpath.
solid answer
~40 s`bannedDependencies` takes `<excludes>` patterns of the form `groupId:artifactId:version:type:scope`, with `*` wildcards, and fails if any match is present transitively — ideal for blocking known-bad or duplicate-purpose artifacts (e.g. `commons-logging`, `log4j:log4j:1.*`, or a CVE-affected version). An `<includes>` block carves exceptions out of a broad ban. `banDuplicateClasses` scans the classpath and fails when the *same fully-qualified class* is provided by more than one jar — the classic 'jar hell' that causes nondeterministic behaviour depending on classpath order. You can `<ignoreClasses>` known-benign overlaps and use `<findAllDuplicates>` for a full report. Together they let a team encode supply-chain and classpath policy directly in the build, so a forbidden or shadowed dependency can never sneak in via a transitive path unnoticed.
code
xml · 6 lines<bannedDependencies>
<excludes>
<exclude>log4j:log4j</exclude>
<exclude>commons-logging:commons-logging</exclude>
</excludes>
</bannedDependencies>go deeper
Knows bannedDependencies blocks forbidden artifacts and duplicate classes are bad.
Writes exclude/include patterns and understands duplicate-class jar hell.
Uses scope-aware bans and ignoreClasses pragmatically, balancing strictness against false positives.
Encodes supply-chain bans (CVEs, deprecated libs) in the corporate parent POM as enforceable policy.
## bannedDependencies Fails the build when an artifact matching a forbidden pattern is on the (transitive) dependency tree. Pattern form: `groupId:artifactId:version:type:scope` — trailing segments are optional and `*` is a wildcard. ```xml <bannedDependencies> <excludes> <exclude>commons-logging:commons-logging</exclude> <exclude>log4j:log4j:1.*</exclude> <exclude>*:*:*:*:test</exclude> </excludes> <includes> <!-- carve an exception out of a broad exclude --> <include>commons-logging:commons-logging:1.2</include> </includes> <message>Use SLF4J/Logback, not the banned logging libraries.</message> </bannedDependencies> ``` Use cases: ban superseded libraries (`commons-logging` when you standardise on SLF4J), ban CVE-affected versions, or ban a transitive that conflicts with a chosen implementation. ## banDuplicateClasses Different from version conflicts: here two *different* artifacts each ship the **same fully-qualified class**. Because the classpath has both, which one loads is order-dependent and fragile ('jar hell'). The rule scans the resolved classpath and fails on overlaps. ```xml <banDuplicateClasses> <ignoreClasses> <ignoreClass>javax.*</ignoreClass> <ignoreClass>module-info</ignoreClass> </ignoreClasses> <findAllDuplicates>true</findAllDuplicates> </banDuplicateClasses> ``` Classic culprits: `javax.*` vs Jakarta artifacts, or repackaged/shaded jars that re-bundle a common library. ## Why both matter for supply-chain hygiene - `bannedDependencies` is a *policy* gate (you decide what is not allowed). - `banDuplicateClasses` is a *correctness* gate (the JVM cannot have two definitions of one class behave predictably). Both run as part of `enforce`, so a transitive dependency dragged in by an upgrade is caught at build time rather than surfacing as a strange runtime error. ## Note on scoping `bannedDependencies` patterns can match by scope, letting you, for example, ban something only in `compile`/`runtime` while tolerating it in `test`.
- How is banDuplicateClasses different from a version conflict?A version conflict is the same artifact at two versions (mediation resolves it); duplicate classes are two different artifacts each shipping the same fully-qualified class, which mediation cannot fix.
- How do you allow one specific version of an otherwise-banned artifact?List the broad pattern under <excludes> and add the permitted coordinate under <includes>, which carves an exception.
saying these in an interview costs you the question
- Confusing bannedDependencies (policy on artifacts) with banDuplicateClasses (same class in two jars).
- Thinking dependency mediation resolves duplicate classes — it does not; it only resolves versions of the same artifact.