skip to content

Shade (Uber-JAR)

Building uber-jars with the Shade plugin: relocating packages, merging service files with transformers, and the dependency-reduced POM it leaves behind. The relocation question is a favorite because it explains why shading fixes conflicts that simple repackaging cannot.

on this pageshow

explore

questions

6

What is an uber-JAR (fat JAR) and how does the maven-shade-plugin build one?

level: juniorimportance: must knowfreq 70%

answer

  1. single self-contained JAR
  2. shade goal -> package phase
  3. unpacks dep classes & merges
  4. ManifestResourceTransformer = main class
  5. vs assembly jar-with-dependencies

basics

~10 s

An uber-JAR is a single JAR that bundles your code plus all dependency classes, so it runs standalone with java -jar. maven-shade-plugin unpacks every dependency JAR and merges the classes into one output JAR.

solid answer

~40 s

An uber-JAR (or fat JAR) is a self-contained JAR containing your compiled classes and the unpacked contents of all your runtime dependencies, so it can run with just `java -jar app.jar` — no external classpath needed. The maven-shade-plugin binds its `shade` goal to the `package` phase; it takes the normal build artifact, extracts every dependency JAR's classes/resources, and repackages them into a single JAR. You typically configure a main class via the `ManifestResourceTransformer` so the JAR is executable. Shade can also rename packages (relocation), merge resource files (transformers), and strip unused classes (`minimizeJar`). The alternative is the maven-assembly-plugin with the `jar-with-dependencies` descriptor, but shade is preferred because it supports relocation and smart resource merging.

code

bash · 3 lines
bash
mvn package
# produces target/my-app-1.0.jar (shaded, runnable)
java -jar target/my-app-1.0.jar

go deeper

for a junior

Knows an uber-JAR is one runnable JAR with all deps and that shade builds it during package.

for a middle

Can write the plugin execution, set the main class via a transformer, and run java -jar.

for a senior

Compares shade vs assembly vs spring-boot plugin and picks per use case; knows default scopes.

for a principal

Sets org-wide conventions on uber-JAR usage (libraries should NOT publish shaded artifacts unshaded-only; reserves fat JARs for apps/CLIs).

## What is an uber-JAR? A normal Maven build produces a JAR with only *your* project's classes. To run it you need every dependency on the classpath. An **uber-JAR** (also called a **fat JAR** or **shaded JAR**) is a single JAR that also contains all the classes from your dependencies, flattened together, so it runs standalone: ``` java -jar my-app.jar ``` ## How maven-shade-plugin builds it The plugin's `shade` goal is bound to the **`package`** lifecycle phase. During `package` it: 1. Takes the project's built artifact (the thin JAR). 2. Resolves the project's dependencies (by default `runtime` + `compile` scope). 3. **Unpacks** each dependency JAR — i.e. extracts the individual `.class` files and resources, not the nested JAR. 4. Merges everything into one output JAR, applying any configured **relocations** (package renames), **transformers** (resource merging), and **minimizeJar** (dead-class removal). 5. By default it **replaces** the main artifact with the shaded one (and writes a `dependency-reduced-pom.xml`). ## Minimal configuration ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.App</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> ``` Run `mvn package`; the uber-JAR appears in `target/`. ## Why shade over alternatives - **maven-assembly-plugin** (`jar-with-dependencies`) also bundles deps but cannot relocate packages or intelligently merge things like `META-INF/services` files. - **spring-boot-maven-plugin** produces a *nested-JAR* executable (deps stay as whole JARs inside `BOOT-INF/lib`) — a different layout that needs Spring Boot's loader. Shade flattens classes, which is what most plain Java/library uber-JARs want.

  • Which dependency scopes get included by default?
    compile and runtime. provided, test, and system are excluded since they aren't needed at runtime in the bundled artifact.
  • What is dependency-reduced-pom.xml?
    A rewritten POM shade installs/deploys in place of the original, with bundled dependencies removed so downstream consumers don't pull them transitively again.

Like packing every ingredient into one ready-to-microwave meal instead of shipping the recipe plus a list of groceries to buy.

saying these in an interview costs you the question

  • Saying shade nests whole dependency JARs inside (that's Spring Boot's layout, not shade — shade unpacks classes)
  • Claiming you must use the assembly plugin for fat JARs
  • Thinking test-scope deps end up in the uber-JAR

context

open as a page

What are shade resource transformers, and why are ServicesResourceTransformer and ManifestResourceTransformer often required?

level: middleimportance: must knowfreq 60%

basics

~10 s

Transformers control how shade merges resource files that exist in multiple dependency JARs. ServicesResourceTransformer concatenates META-INF/services files so SPI lookups still work; ManifestResourceTransformer builds the merged manifest, e.g. setting Main-Class.

open as a page

What is package relocation (shading) in maven-shade-plugin and what problem does it solve?

level: seniorimportance: must knowfreq 65%

basics

~10 s

Relocation rewrites a dependency's package names (and the bytecode references to them) to a new prefix inside your uber-JAR. It prevents version conflicts when consumers also use a different version of that same library.

open as a page

What does minimizeJar do in maven-shade-plugin, and what are its risks?

level: seniorimportance: should knowfreq 45%

basics

~10 s

minimizeJar makes shade strip out dependency classes that aren't reachable from your code, shrinking the uber-JAR. The risk is it may remove classes only loaded via reflection or SPI, causing ClassNotFoundException at runtime.

open as a page

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

level: seniorimportance: should knowfreq 40%

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.

open as a page

When would you choose maven-shade-plugin over the spring-boot-maven-plugin or maven-assembly-plugin for packaging?

level: principalimportance: should knowfreq 35%

basics

~20 s

Use shade when you need a flattened uber-JAR with package relocation and smart resource merging — typically for libraries, Maven plugins, or big-data jobs. Use spring-boot-maven-plugin for Spring Boot apps, and assembly only for simple bundles or non-JAR archives.

open as a page