|
1 | 1 | # Controlling JAR Content Merging
|
2 | 2 |
|
3 | 3 | Shadow allows for customizing the process by which the output JAR is generated through the
|
4 |
| -[`Transformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-transformer/index.html) interface. |
| 4 | +[`ResourceTransformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-resource-transformer/index.html) interface. |
5 | 5 | This is a concept that has been carried over from the original Maven Shade implementation.
|
6 |
| -A [`Transformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-transformer/index.html) is invoked for each |
| 6 | +A [`ResourceTransformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-resource-transformer/index.html) is invoked for each |
7 | 7 | entry in the JAR before being written to the final output JAR.
|
8 |
| -This allows a [`Transformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-transformer/index.html) to |
| 8 | +This allows a [`ResourceTransformer`](https://gradleup.com/shadow/api/shadow/com.github.jengelman.gradle.plugins.shadow.transformers/-resource-transformer/index.html) to |
9 | 9 | determine if it should process a particular entry and apply any modifications before writing the stream to the output.
|
10 | 10 |
|
11 | 11 | === "Kotlin"
|
@@ -48,7 +48,7 @@ determine if it should process a particular entry and apply any modifications be
|
48 | 48 | }
|
49 | 49 | ```
|
50 | 50 |
|
51 |
| -Additionally, a `Transformer` can accept a `Closure` to configure the provided `Transformer`. |
| 51 | +Additionally, a `ResourceTransformer` can accept a `Closure` to configure the provided `ResourceTransformer`. |
52 | 52 |
|
53 | 53 | === "Kotlin"
|
54 | 54 |
|
@@ -95,7 +95,7 @@ Additionally, a `Transformer` can accept a `Closure` to configure the provided `
|
95 | 95 | }
|
96 | 96 | ```
|
97 | 97 |
|
98 |
| -An instantiated instance of a `Transformer` can also be provided. |
| 98 | +An instantiated instance of a `ResourceTransformer` can also be provided. |
99 | 99 |
|
100 | 100 | === "Kotlin"
|
101 | 101 |
|
@@ -254,7 +254,7 @@ method to add this transformer.
|
254 | 254 |
|
255 | 255 | ## Merging Log4j2 Plugin Cache Files (`Log4j2Plugins.dat`)
|
256 | 256 |
|
257 |
| -`Log4j2PluginsCacheFileTransformer` is a `Transformer` that merges `META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat` plugin caches from all the jars |
| 257 | +`Log4j2PluginsCacheFileTransformer` is a `ResourceTransformer` that merges `META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat` plugin caches from all the jars |
258 | 258 | containing Log4j 2.x Core components. It's a Gradle equivalent of [Log4j Plugin Descriptor Transformer](https://logging.apache.org/log4j/transform/log4j-transform-maven-shade-plugin-extensions.html#log4j-plugin-cache-transformer).
|
259 | 259 |
|
260 | 260 | === "Kotlin"
|
@@ -355,3 +355,45 @@ It must be added using the [`transform`](https://gradleup.com/shadow/api/shadow/
|
355 | 355 | }
|
356 | 356 | }
|
357 | 357 | ```
|
| 358 | + |
| 359 | +## Handling Duplicates Strategy |
| 360 | + |
| 361 | +`ShadowJar` is a subclass of |
| 362 | +[`org.gradle.api.tasks.AbstractCopyTask`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.AbstractCopyTask.html), |
| 363 | +which means it honors the `duplicatesStrategy` property as its parent classes do. There are several strategies to handle: |
| 364 | + |
| 365 | +- `EXCLUDE`: Do not allow duplicates by ignoring subsequent items to be created at the same path. |
| 366 | +- `FAIL`: Throw a `DuplicateFileCopyingException` when subsequent items are to be created at the same path. |
| 367 | +- `INCLUDE`: Do not attempt to prevent duplicates. |
| 368 | +- `INHERIT`: Uses the same strategy as the parent copy specification. |
| 369 | +- `WARN`: Do not attempt to prevent duplicates, but log a warning message when multiple items are to be created at the same path. |
| 370 | + |
| 371 | +You can see more details about them in |
| 372 | +[`DuplicatesStrategy`](https://docs.gradle.org/current/javadoc/org/gradle/api/file/DuplicatesStrategy.html). |
| 373 | + |
| 374 | +`ShadowJar` recognizes `DuplicatesStrategy.INCLUDE` as the default, if you want to change the strategy, you can |
| 375 | +override it like: |
| 376 | + |
| 377 | +=== "Kotlin" |
| 378 | + |
| 379 | + ```kotlin |
| 380 | + tasks.shadowJar { |
| 381 | + duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else. |
| 382 | + } |
| 383 | + ``` |
| 384 | + |
| 385 | +=== "Groovy" |
| 386 | + |
| 387 | + ```groovy |
| 388 | + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { |
| 389 | + duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else. |
| 390 | + } |
| 391 | + ``` |
| 392 | + |
| 393 | +Different strategies will lead to different results for `foo/bar` files in the JARs to be merged: |
| 394 | + |
| 395 | +- `EXCLUDE`: The **first** `foo/bar` file will be included in the final JAR. |
| 396 | +- `FAIL`: **Fail** the build with a `DuplicateFileCopyingException` if there are duplicated `foo/bar` files. |
| 397 | +- `INCLUDE`: The **last** `foo/bar` file will be included in the final JAR (the default behavior). |
| 398 | +- `INHERIT`: **Fail** the build with an exception like `Entry .* is a duplicate but no duplicate handling strategy has been set`. |
| 399 | +- `WARN`: The **last** `foo/bar` file will be included in the final JAR, and a warning message will be logged. |
0 commit comments