Deduplicating Resource Transformer
Transformer to include files with identical content only once in the shadowed JAR.
Multiple files with the same path but different content lead to an error.
Some scenarios for duplicate resources in a shadow jar:
Duplicate
.classfiles Having duplicate.classfiles with different content is a situation indicating that the resulting jar is built with incompatible classes, likely leading to issues during runtime. This situation can happen when one dependency is (also) included in an uber jar.Duplicate
META-INF/<group-id>/<artifact-id>/pom.properties/xmlfiles. Some dependencies contain shaded variants of other dependencies. Tools that inspect jar files to extract the included dependencies, for example, for license auditing use cases or tools that collect information of all included dependencies, may rely on these files. Hence, it is desirable to retain the duplicate resourcepom.properties/xmlresources.
DeduplicatingResourceTransformer checks all entries in the resulting jar. It is generally not recommended to use any of the include configuration functions.
There are reasons to retain duplicate resources with different contents in the resulting jar. This can be achieved with the exclude configuration functions.
To exclude a path or pattern from being deduplicated, for example, legit META-INF/<group-id>/<artifact-id>/pom.properties/xml, configure the transformer with an exclusion like the following:
tasks.shadowJar {
transform(DeduplicatingResourceTransformer::class.java) {
// Keep pom.* files from different Guava versions in the jar.
exclude("META-INF/maven/com.google.guava/guava/pom.*")
// Duplicates with different content for all other resource paths will raise an error.
}
}Tip: the FindResourceInClasspath convenience task can be used to find resources in a Gradle classpath/configuration.
Warning Do not combine PreserveFirstFoundResourceTransformer with this transformer, as they handle duplicates differently and combining them would lead to redundant or unexpected behavior.
Constructors
Properties
This is used for creating Gradle's lazy properties in the subclass, Shadow's build-in transformers that depend on this have been injected via ObjectFactory.newInstance. Custom transformers should implement or inject this property if they need to access it.