Skip to content

Commit 46d7be1

Browse files
authored
Pin the handling DuplicatesStrategy section (#1619)
1 parent 67dd06f commit 46d7be1

File tree

1 file changed

+76
-75
lines changed

1 file changed

+76
-75
lines changed

docs/configuration/merging/README.md

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,82 @@ should process a particular entry and apply any modifications before writing the
1414
This ordering is crucial when merging configuration files where you want to preserve project-specific values while
1515
merging in additional data from dependencies.
1616

17+
## Handling Duplicates Strategy
18+
19+
`ShadowJar` is a subclass of [`org.gradle.api.tasks.AbstractCopyTask`][AbstractCopyTask], which means it honors the
20+
`duplicatesStrategy` property as its parent classes do. There are several strategies to handle:
21+
22+
- `EXCLUDE`: Do not allow duplicates by ignoring subsequent items to be created at the same path.
23+
- `FAIL`: Throw a `DuplicateFileCopyingException` when subsequent items are to be created at the same path.
24+
- `INCLUDE`: Do not attempt to prevent duplicates.
25+
- `INHERIT`: Uses the same strategy as the parent copy specification.
26+
- `WARN`: Do not attempt to prevent duplicates, but log a warning message when multiple items are to be created at the
27+
same path.
28+
29+
see more details about them in [`DuplicatesStrategy`][DuplicatesStrategy].
30+
31+
`ShadowJar` recognizes `DuplicatesStrategy.INCLUDE` as the default, if you want to change the strategy, you can
32+
override it like:
33+
34+
=== "Kotlin"
35+
36+
```kotlin
37+
tasks.shadowJar {
38+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else.
39+
}
40+
```
41+
42+
=== "Groovy"
43+
44+
```groovy
45+
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
46+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else.
47+
}
48+
```
49+
50+
Different strategies will lead to different results for `foo/bar` files in the JARs to be merged:
51+
52+
- `EXCLUDE`: The **first** `foo/bar` file will be included in the final JAR.
53+
- `FAIL`: **Fail** the build with a `DuplicateFileCopyingException` if there are duplicate `foo/bar` files.
54+
- `INCLUDE`: Duplicate `foo/bar` entries will be included in the final JAR.
55+
- `INHERIT`: **Fail** the build with an exception like
56+
`Entry .* is a duplicate but no duplicate handling strategy has been set`.
57+
- `WARN`: **Warn** about duplicates in the build log, this behaves exactly as `INHERIT` otherwise.
58+
59+
**NOTE:** The `duplicatesStrategy` takes precedence over transforming and relocating. If you mix the usages of
60+
`duplicatesStrategy` and [`ResourceTransformer`][ResourceTransformer] like below:
61+
62+
=== "Kotlin"
63+
64+
```kotlin
65+
tasks.shadowJar {
66+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
67+
mergeServiceFiles()
68+
}
69+
```
70+
71+
=== "Groovy"
72+
73+
```groovy
74+
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
75+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
76+
mergeServiceFiles()
77+
}
78+
```
79+
80+
The [`ResourceTransformer`][ResourceTransformer]s like [`ServiceFileTransformer`][ServiceFileTransformer] will not work
81+
as expected because the `duplicatesStrategy` will exclude the duplicate service files beforehand. However, this behavior might be what you expected for duplicate
82+
`foo/bar` files, preventing them from being included.
83+
84+
Want [`ResourceTransformer`][ResourceTransformer]s and `duplicatesStrategy` to work together? There are several ways to
85+
do it:
86+
87+
- Use [`filesMatching`][Jar.filesMatching] to override the strategy for specific files.
88+
- Keep `duplicatesStrategy = INCLUDE` and write your own [`ResourceTransformer`][ResourceTransformer] to handle duplicates.
89+
90+
If you just want to keep the current behavior and preserve the first found resources, there is a simple built-in one
91+
called [`PreserveFirstFoundResourceTransformer`][PreserveFirstFoundResourceTransformer].
92+
1793
## Basic ResourceTransformer Usage
1894

1995
For simpler use cases, you can create a basic transformer:
@@ -360,81 +436,6 @@ It must be added using the [`transform`][ShadowJar.transform] methods.
360436
}
361437
```
362438

363-
## Handling Duplicates Strategy
364-
365-
`ShadowJar` is a subclass of [`org.gradle.api.tasks.AbstractCopyTask`][AbstractCopyTask], which means it honors the
366-
`duplicatesStrategy` property as its parent classes do. There are several strategies to handle:
367-
368-
- `EXCLUDE`: Do not allow duplicates by ignoring subsequent items to be created at the same path.
369-
- `FAIL`: Throw a `DuplicateFileCopyingException` when subsequent items are to be created at the same path.
370-
- `INCLUDE`: Do not attempt to prevent duplicates.
371-
- `INHERIT`: Uses the same strategy as the parent copy specification.
372-
- `WARN`: Do not attempt to prevent duplicates, but log a warning message when multiple items are to be created at the
373-
same path.
374-
375-
see more details about them in [`DuplicatesStrategy`][DuplicatesStrategy].
376-
377-
`ShadowJar` recognizes `DuplicatesStrategy.INCLUDE` as the default, if you want to change the strategy, you can
378-
override it like:
379-
380-
=== "Kotlin"
381-
382-
```kotlin
383-
tasks.shadowJar {
384-
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else.
385-
}
386-
```
387-
388-
=== "Groovy"
389-
390-
```groovy
391-
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
392-
duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or something else.
393-
}
394-
```
395-
396-
Different strategies will lead to different results for `foo/bar` files in the JARs to be merged:
397-
398-
- `EXCLUDE`: The **first** `foo/bar` file will be included in the final JAR.
399-
- `FAIL`: **Fail** the build with a `DuplicateFileCopyingException` if there are duplicate `foo/bar` files.
400-
- `INCLUDE`: Duplicate `foo/bar` entries will be included in the final JAR.
401-
- `INHERIT`: **Fail** the build with an exception like
402-
`Entry .* is a duplicate but no duplicate handling strategy has been set`.
403-
- `WARN`: **Warn** about duplicates in the build log, this behaves exactly as `INHERIT` otherwise.
404-
405-
**NOTE:** The `duplicatesStrategy` takes precedence over transforming and relocating. If you mix the usages of
406-
`duplicatesStrategy` and [`ResourceTransformer`][ResourceTransformer] like below:
407-
408-
=== "Kotlin"
409-
410-
```kotlin
411-
tasks.shadowJar {
412-
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
413-
mergeServiceFiles()
414-
}
415-
```
416-
417-
=== "Groovy"
418-
419-
```groovy
420-
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
421-
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
422-
mergeServiceFiles()
423-
}
424-
```
425-
426-
The [`ResourceTransformer`][ResourceTransformer]s like [`ServiceFileTransformer`][ServiceFileTransformer] will not work
427-
as expected because the `duplicatesStrategy` will exclude the duplicate service files beforehand. However, this behavior might be what you expected for duplicate
428-
`foo/bar` files, preventing them from being included.
429-
430-
Want [`ResourceTransformer`][ResourceTransformer]s and `duplicatesStrategy` to work together? There are several ways to
431-
do it:
432-
433-
- Use [`filesMatching`][Jar.filesMatching] to override the strategy for specific files.
434-
- Keep `duplicatesStrategy = INCLUDE` and write your own [`ResourceTransformer`][ResourceTransformer] to handle duplicates.
435-
436-
If you just want to keep the current behavior and preserve the first found resources, there is a simple built-in one
437-
called [`PreserveFirstFoundResourceTransformer`][PreserveFirstFoundResourceTransformer].
438439

439440

440441
[AbstractCopyTask]: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.AbstractCopyTask.html

0 commit comments

Comments
 (0)