What is dependency:copy-dependencies for, and how is it different from building a fat/shaded jar?
answer
- copies dep jars to target/dependency
- separate files, not merged
- stripVersion / includeScope
- Docker layer caching
- vs shade fat-jar
basics
~20 sdependency:copy-dependencies copies your project's resolved dependency jars into a folder (default target/dependency). Unlike a fat/shaded jar, it leaves them as separate files — useful for a Class-Path/-cp layout or for Docker images that cache deps separately from app code.
solid answer
~40 sThe `copy-dependencies` goal of the `maven-dependency-plugin` writes the project's resolved dependency artifacts into an output directory (default `${project.build.directory}/dependency`). You can filter by scope (`includeScope=runtime`), strip versions from filenames (`stripVersion`), and target a custom `outputDirectory`. It keeps each dependency as a discrete jar, which contrasts with the **maven-shade-plugin** (relocates and merges everything into one über-jar) and **spring-boot-maven-plugin**'s nested-jar layout. Separate jars are valuable for: a classic `lib/` directory referenced by a manifest `Class-Path`; container images where dependency jars sit in a stable, cacheable layer apart from the frequently-changing application jar; and tooling/inspection. There's also `dependency:copy` (a single specified artifact) and `dependency:unpack`/`unpack-dependencies` for extracting contents rather than copying jars.
code
bash · 1 linemvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/libsgo deeper
Knows it copies dependency jars into a folder.
Configures scope/output and explains the difference from a fat jar.
Chooses between copy-dependencies, shade, and Spring Boot layout based on caching and conflict needs.
Defines packaging/layering standards for container image build efficiency across services.
## The goal `mvn dependency:copy-dependencies` resolves the project's dependencies and copies each resolved jar into an output directory. Defaults to `target/dependency`. ## Useful configuration - `outputDirectory` — where to put them (e.g. `${project.build.directory}/libs`). - `includeScope` / `excludeScope` — e.g. `runtime` to skip test/provided. - `stripVersion` / `stripClassifier` — produce `lib/foo.jar` instead of `lib/foo-1.2.3.jar`. - `includeArtifactIds` / `excludeGroupIds` — fine-grained filters. ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-deps</id> <phase>package</phase> <goals><goal>copy-dependencies</goal></goals> <configuration> <outputDirectory>${project.build.directory}/libs</outputDirectory> <includeScope>runtime</includeScope> </configuration> </execution> </executions> </plugin> ``` ## vs fat/shaded jar - **maven-shade-plugin**: merges all classes (yours + dependencies) into one über-jar and can *relocate* packages to avoid conflicts. One file, self-contained, but opaque and harder to cache. - **spring-boot-maven-plugin**: nests dependency jars inside an executable jar with a custom loader. - **copy-dependencies**: keeps jars **separate**. You then run with `java -cp 'app.jar:libs/*' Main` or set the jar manifest `Class-Path` (via maven-jar-plugin). ## Why separate jars - **Container layer caching**: put `libs/` in an earlier Docker layer than the app jar; dependencies change rarely, app code changes often, so rebuilds stay fast. - **Classic lib/ deployments** and tooling that needs to scan individual artifacts. ## Related goals - `dependency:copy` — copy one explicitly listed artifact. - `dependency:unpack` / `unpack-dependencies` — extract jar contents instead of copying the jars.
- How does copy-dependencies differ from maven-shade-plugin?Shade merges all classes into a single relocatable uber-jar; copy-dependencies leaves each dependency as a separate jar in a directory, which you reference via classpath or manifest Class-Path.
- Why is the separate-jar layout good for Docker images?Dependency jars change rarely, so they go in an early, cacheable layer; the app jar changes often and sits in a later layer, keeping rebuilds fast.
saying these in an interview costs you the question
- Saying it produces an executable/fat jar
- Confusing copy-dependencies with copy (single artifact)
- Thinking it merges classes