Safeguard
Supply Chain•

How do I migrate Maven exclusions to Gradle correctly?

Find out why each Maven exclusion exists, then pick a Gradle exclude, constraint or version override. Copying exclusions blindly can reopen old risks.

Safeguard Security Team
3 min read

Do not copy Maven exclusions one for one. First write down why each exists: a vulnerable version, a conflicting library, or an unwanted dependency. Then pick the Gradle tool that matches that reason, whether an exclude, a constraint or a version override. The Gradle migration guide says you need to understand the reason to migrate it properly.

Exclusions hide intent

A Maven exclusion is one XML element that says remove this. It does not say why. Over years a project collects them: one to dodge a logging library conflict, one to drop a transitive package that had a known flaw, one for a license. The Gradle migration guide states that exclusions keep unwanted dependencies, or unwanted versions of dependencies, out of the graph, and that in Gradle other options may be more appropriate, so you really need to understand why an exclusion is in place.

Sort each exclusion by reason

ReasonBetter Gradle approach
Keep a vulnerable version outA dependency constraint that sets a safe floor
Pick one of two versionsVersion control mechanisms, not removal
Drop an unneeded libraryAn exclusion on the configuration or the dependency
Two libraries provide the same thingCapability conflict handling

For version motivated exclusions, the guide points to the section on controlling dependency versions: dependency constraints, BOMs and overriding transitive versions. For reasons unrelated to versions, it shows how to attach an exclusion to an entire configuration, which is often the most appropriate solution, to a single dependency, or to all configurations.

Steps

  1. Search the POMs for exclusion elements and list them.
  2. For each, check version control history or ask the author for the reason.
  3. If no reason can be found, test removing the exclusion in a branch and see what changes in the resolved tree. Leave a comment explaining the decision either way.
  4. Express the surviving ones in Gradle with the matching mechanism and a because note where supported. See Gradle constraints with because.
  5. Diff the resolved trees (see verify resolved versions after switching package managers).

The risk of getting it wrong

If an exclusion existed to keep a vulnerable transitive version out and the Gradle build does not reproduce that, the vulnerable package returns. Because Gradle picks the highest version by default, the problem may even fix itself, but you should confirm, not hope. The reverse also happens: an exclude that removes a module that something needs at runtime fails only in production.

Another subtle point is optional dependencies. The guide says Gradle, like Maven, ignores transitive dependencies declared as optional, so they are not resolved and do not influence version selection.

Keep a record

Add a short comment above every migrated exclusion stating the reason and the date. A future maintainer will otherwise delete it or copy it forever. Related reading: exclude a vulnerable transitive dependency in Maven.

Safeguard's dependency scanning can confirm after the migration that no vulnerable version came back. Try the free scan at gold.safeguard.sh/scan.

Quick check

Can I just replicate every exclusion as is?

You can, but it may be the wrong tool. Match the mechanism to the reason, using constraints for versions and exclusions for removal.

How do I know an exclusion is still needed?

Remove it on a branch, rebuild, and compare the resolved tree. If nothing relevant changes, consider dropping it.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.