Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin.
Calling minimize() shouldn't trigger an error/warning when duplicatesStrategy is changed from the default
Related environent and versions
gradle wrapper 8.7, but I tested similar projects with gradle 8.8, 8.9, and 8.10
plugin version 8.3.0, but I tested similar projects with versions 8.1.0 and 8.1.1 from the johnrengelman plugin
KotlinDSL
tested with java 8, 17, and 21
Win10 22H2 19045.4780
Reproduction steps
In a blank hello-world-project, call minimize() when configuring shadowJar
setting duplicatesStrategy = DuplicatesStrategy.FAIL and calling shadowJar will fail the build (saying that MANIFEST.MF has already been copied)
setting duplicatesStrategy = DuplicatesStrategy.EXCLUDE and calling shadowJar will make an empty jar (or rather a jar with a single entry foo/bar/, with no files inside)
setting duplicatesStrategy = DuplicatesStrategy.WARN and calling shadowJar will trigger warnings for each class and jar
Anything else?
build.gradle.kts
plugins {
java
id("com.gradleup.shadow") version "8.3.0"
}
group = "foo.bar"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
// Sample dependency, it is not a guava thing. It even fails without dependencies
implementation("com.google.guava:guava:33.3.0-jre")
}
tasks.shadowJar {
minimize()
duplicatesStrategy = DuplicatesStrategy.WARN
}
D:\code\java\bug_report>gradlew clean shadowJar
> Task :shadowJar
MANIFEST.MF will be copied to 'META-INF/MANIFEST.MF', overwriting MANIFEST.MF, which has already been copied there.
file 'D:\code\java\bug_report\build\classes\java\main\foo\bar\Main.class' will be copied to 'foo/bar/Main.class', overwriting file 'D:\code\java\bug_report\build\classes\java\main\foo\bar\Main.class', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\guava\33.3.0-jre\13b4d0924e6023eda04b4c7aa83b32dfedf735a7\guava-33.3.0-jre.jar' will be copied to 'guava-33.3.0-jre.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\guava\33.3.0-jre\13b4d0924e6023eda04b4c7aa83b32dfedf735a7\guava-33.3.0-jre.jar', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\failureaccess\1.0.2\c4a06a64e650562f30b7bf9aaec1bfed43aca12b\failureaccess-1.0.2.jar' will be copied to 'failureaccess-1.0.2.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\failureaccess\1.0.2\c4a06a64e650562f30b7bf9aaec1bfed43aca12b\failureaccess-1.0.2.jar', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\b421526c5f297295adef1c886e5246c39d4ac629\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar' will be copied to 'listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\b421526c5f297295adef1c886e5246c39d4ac629\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.code.findbugs\jsr305\3.0.2\25ea2e8b0c338a877313bd4672d3fe056ea78f0d\jsr305-3.0.2.jar' will be copied to 'jsr305-3.0.2.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.code.findbugs\jsr305\3.0.2\25ea2e8b0c338a877313bd4672d3fe056ea78f0d\jsr305-3.0.2.jar', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\org.checkerframework\checker-qual\3.43.0\9425eee39e56b116d2b998b7c2cebcbd11a3c98b\checker-qual-3.43.0.jar' will be copied to 'checker-qual-3.43.0.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\org.checkerframework\checker-qual\3.43.0\9425eee39e56b116d2b998b7c2cebcbd11a3c98b\checker-qual-3.43.0.jar', which has already been copied there.
file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.errorprone\error_prone_annotations\2.28.0\59fc00087ce372de42e394d2c789295dff2d19f0\error_prone_annotations-2.28.0.jar' will be copied to 'error_prone_annotations-2.28.0.jar', overwriting file 'D:\code\.gradle\caches\modules-2\files-2.1\com.google.errorprone\error_prone_annotations\2.28.0\59fc00087ce372de42e394d2c789295dff2d19f0\error_prone_annotations-2.28.0.jar', which has already been copied there.
Expected and Results
Calling
minimize()
shouldn't trigger an error/warning whenduplicatesStrategy
is changed from the defaultRelated environent and versions
gradle wrapper 8.7, but I tested similar projects with gradle 8.8, 8.9, and 8.10 plugin version 8.3.0, but I tested similar projects with versions 8.1.0 and 8.1.1 from the johnrengelman plugin KotlinDSL tested with java 8, 17, and 21 Win10 22H2 19045.4780
Reproduction steps
minimize()
when configuringshadowJar
duplicatesStrategy = DuplicatesStrategy.FAIL
and callingshadowJar
will fail the build (saying that MANIFEST.MF has already been copied)duplicatesStrategy = DuplicatesStrategy.EXCLUDE
and callingshadowJar
will make an empty jar (or rather a jar with a single entryfoo/bar/
, with no files inside)duplicatesStrategy = DuplicatesStrategy.WARN
and callingshadowJar
will trigger warnings for each class and jarAnything else?
build.gradle.kts