What is an uber-JAR (fat JAR) and how does the maven-shade-plugin build one?
answer
- single self-contained JAR
- shade goal -> package phase
- unpacks dep classes & merges
- ManifestResourceTransformer = main class
- vs assembly jar-with-dependencies
basics
~10 sAn 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 sAn 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 linesmvn package
# produces target/my-app-1.0.jar (shaded, runnable)
java -jar target/my-app-1.0.jargo deeper
Knows an uber-JAR is one runnable JAR with all deps and that shade builds it during package.
Can write the plugin execution, set the main class via a transformer, and run java -jar.
Compares shade vs assembly vs spring-boot plugin and picks per use case; knows default scopes.
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