skip to content

What is the dependency-reduced-pom.xml that maven-shade-plugin generates, and why does it matter?

level: seniorimportance: should knowfreq 40%

answer

  1. rewritten POM installed instead of original
  2. strips bundled deps from <dependencies>
  3. prevents transitive double-pull
  4. createDependencyReducedPom default true
  5. written to basedir -> gitignore it

basics

~10 s

It's a rewritten POM shade installs/deploys instead of the original, with the bundled dependencies removed from <dependencies>. This stops consumers of your uber-JAR from transitively pulling those same dependencies again.

solid answer

~40 s

When shade replaces the main artifact, it also generates `dependency-reduced-pom.xml` and installs/deploys *that* instead of your original POM. The point: your uber-JAR already contains the bundled dependencies' classes, so if the published POM still listed them, consumers would transitively download duplicates — causing classpath duplication and version conflicts. The reduced POM strips out the dependencies that were shaded in (keeping `provided`/`test`/excluded ones). Behaviour is controlled by `createDependencyReducedPom` (default true) and `dependencyReducedPomLocation`. Gotchas: the file is written to the project basedir by default and can clutter the repo (people gitignore it); and if you `relocate` but don't reduce, or reduce incorrectly, downstream classpaths get confused. For application uber-JARs that nobody depends on, the reduced POM is mostly irrelevant; it matters most when publishing a shaded *library*.

code

xml · 5 lines
xml
<configuration>
  <createDependencyReducedPom>false</createDependencyReducedPom>
  <!-- or relocate it out of the repo root: -->
  <!-- <dependencyReducedPomLocation>${project.build.directory}/reduced-pom.xml</dependencyReducedPomLocation> -->
</configuration>

go deeper

for a junior

Has seen the file appear and knows it's auto-generated by shade.

for a middle

Knows it removes bundled deps from the published POM and can toggle createDependencyReducedPom.

for a senior

Explains the transitive double-pull problem and decides when to disable or relocate it.

for a principal

Sets conventions for publishing shaded libraries vs apps and how the reduced POM interacts with the org's dependency-management discipline.

## The problem it solves Shade replaces your normal artifact with the uber-JAR, which already *contains* the bundled dependencies' classes. But Maven publishes a **POM** alongside every artifact, and that POM lists `<dependencies>`. If the published POM still declared the bundled libraries, anyone depending on your artifact would **transitively pull those same libraries again** — getting two copies of the classes (one inside your uber-JAR, one external) and potential version conflicts. ## What dependency-reduced-pom.xml is Shade generates a modified copy of your POM with the **shaded-in dependencies removed** from `<dependencies>`, and installs/deploys *this* reduced POM in place of the original. So consumers see a clean dependency list reflecting only what your artifact truly needs externally. ## Controlling it ```xml <configuration> <createDependencyReducedPom>true</createDependencyReducedPom> <!-- default true --> <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation> </configuration> ``` - `createDependencyReducedPom` — set `false` to skip it (common for plain application fat JARs nobody depends on). - `dependencyReducedPomLocation` — by default it's written to the **project basedir** (next to `pom.xml`), which surprises people; many move it under `target/` or gitignore it. - `promoteTransitiveDependencies` — pulls transitive deps up as direct ones in the reduced POM when needed. ## Which dependencies are kept vs removed - **Removed**: dependencies actually shaded into the uber-JAR (compile/runtime that got bundled). - **Kept**: `provided` and `test` scope (not bundled anyway), and anything explicitly excluded from shading via filters. ## When it matters / gotchas - **Matters most for published shaded libraries** — gets the downstream classpath right. - **Largely irrelevant for leaf application uber-JARs** — nothing depends on them, so you can disable it. - **Repo clutter**: the default basedir location means a stray `dependency-reduced-pom.xml` shows up in version control; add it to `.gitignore` or relocate it. - If you disable it but still publish, consumers double-pull the bundled deps.

  • When is it safe to set createDependencyReducedPom=false?
    For a leaf application/CLI uber-JAR that no other module depends on; consumers' transitive resolution is irrelevant there.
  • Why do teams gitignore dependency-reduced-pom.xml?
    By default shade writes it to the project basedir next to pom.xml, so it shows up as an untracked file on every build.

Like shipping a fully assembled appliance but updating the parts list so the buyer doesn't also order all the screws you already installed.

saying these in an interview costs you the question

  • Saying the reduced POM is your real source POM (it's a generated copy used only for install/deploy)
  • Thinking it removes ALL dependencies (provided/test/excluded stay)
  • Believing it changes the uber-JAR contents (it only changes the published POM)

context