Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/shadow.api
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar
public final fun minimize ()V
public fun minimize (Lorg/gradle/api/Action;)V
public static synthetic fun minimize$default (Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar;Lorg/gradle/api/Action;ILjava/lang/Object;)V
public final fun r8 ()V
public fun r8 (Lorg/gradle/api/Action;)V
public static synthetic fun r8$default (Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar;Lorg/gradle/api/Action;ILjava/lang/Object;)V
public final fun relocate (Lcom/github/jengelman/gradle/plugins/shadow/relocation/Relocator;)V
public fun relocate (Lcom/github/jengelman/gradle/plugins/shadow/relocation/Relocator;Lorg/gradle/api/Action;)V
public final fun relocate (Ljava/lang/Class;)V
Expand Down
2 changes: 2 additions & 0 deletions docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
### Deprecated

- Deprecate `keepRules` and `keepRuleFiles` in `R8Spec`. ([#2120](https://github.com/GradleUp/shadow/pull/2120))
- Deprecate `minimize { r8 { ... } }` in favor of the standalone `r8 { ... }` block. ([#2123](https://github.com/GradleUp/shadow/pull/2123))
The previous DSL remains available as a compatibility layer until Shadow 10.

## [9.6.1](https://github.com/GradleUp/shadow/releases/tag/9.6.1) - 2026-07-22

Expand Down
82 changes: 33 additions & 49 deletions docs/configuration/minimizing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,19 @@ Similar to [`ShadowJar.dependencies`][ShadowJar.dependencies], projects can also
> When excluding a `project`, all dependencies of the excluded `project` are automatically excluded from
> minimization as well.

## Minimizing with R8
## Post-processing with R8

Shadow can also run [R8](https://r8.googlesource.com/r8) over the final shadowed JAR. This is useful when you want
whole-program shrinking instead of the default dependency analyzer. R8 runs after Shadow has merged, transformed, and
relocated the JAR, so service descriptors in `META-INF/services` are used to keep service providers.
whole-program shrinking independently of the default dependency analyzer. R8 runs after Shadow has merged,
transformed, relocated, and optionally minimized the JAR, so service descriptors in `META-INF/services` are used to
keep service providers.

The default R8 configuration only shrinks unused code. It disables name minification and optimization.
Shadow also extracts R8 rules published in dependency JARs, for example under `META-INF/proguard`.

The `minimize` and `r8` blocks are independent and can be enabled separately or together. Dependency exclusions in
`minimize` only configure Shadow's dependency analyzer; use ProGuard rules to keep classes during R8 post-processing.

=== "Kotlin"

```kotlin
Expand All @@ -89,12 +93,10 @@ Shadow also extracts R8 rules published in dependency JARs, for example under `M
}

tasks.shadowJar {
minimize {
r8 {
// Optional extra configuration
proguardRules.add("-keep class com.example.ReflectiveApi { *; }")
proguardRuleFiles.from(layout.projectDirectory.file("r8-rules.pro"))
}
r8 {
// Optional extra configuration
proguardRules.add("-keep class com.example.ReflectiveApi { *; }")
proguardRuleFiles.from(layout.projectDirectory.file("r8-rules.pro"))
}
}
```
Expand All @@ -107,12 +109,10 @@ Shadow also extracts R8 rules published in dependency JARs, for example under `M
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
minimize {
r8 {
// Optional extra configuration
proguardRules.add('-keep class com.example.ReflectiveApi { *; }')
proguardRuleFiles.from(layout.projectDirectory.file('r8-rules.pro'))
}
r8 {
// Optional extra configuration
proguardRules.add('-keep class com.example.ReflectiveApi { *; }')
proguardRuleFiles.from(layout.projectDirectory.file('r8-rules.pro'))
}
}
```
Expand Down Expand Up @@ -150,10 +150,8 @@ For example, to downgrade R8 warnings to info:
}

tasks.shadowJar {
minimize {
r8 {
args.addAll(listOf("--map-diagnostics", "warning", "info"))
}
r8 {
args.addAll(listOf("--map-diagnostics", "warning", "info"))
}
}
```
Expand All @@ -166,10 +164,8 @@ For example, to downgrade R8 warnings to info:
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
minimize {
r8 {
args.addAll(['--map-diagnostics', 'warning', 'info'])
}
r8 {
args.addAll(['--map-diagnostics', 'warning', 'info'])
}
}
```
Expand All @@ -184,10 +180,8 @@ To enable name obfuscation:
}

tasks.shadowJar {
minimize {
r8 {
enableObfuscation()
}
r8 {
enableObfuscation()
}
}
```
Expand All @@ -200,10 +194,8 @@ To enable name obfuscation:
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
minimize {
r8 {
enableObfuscation()
}
r8 {
enableObfuscation()
}
}
```
Expand All @@ -218,10 +210,8 @@ To enable optimization:
}

tasks.shadowJar {
minimize {
r8 {
enableOptimization()
}
r8 {
enableOptimization()
}
}
```
Expand All @@ -234,10 +224,8 @@ To enable optimization:
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
minimize {
r8 {
enableOptimization()
}
r8 {
enableOptimization()
}
}
```
Expand All @@ -252,11 +240,9 @@ To enable both:
}

tasks.shadowJar {
minimize {
r8 {
enableObfuscation()
enableOptimization()
}
r8 {
enableObfuscation()
enableOptimization()
}
}
```
Expand All @@ -269,11 +255,9 @@ To enable both:
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
minimize {
r8 {
enableObfuscation()
enableOptimization()
}
r8 {
enableObfuscation()
enableOptimization()
}
}
```
Expand Down
2 changes: 2 additions & 0 deletions docs/getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ Here are the options that can be passed to the `shadowJar`:
--no-add-multi-release-attribute Disables option --add-multi-release-attribute.
--enable-auto-relocation Enables auto relocation of packages in the dependencies.
--no-enable-auto-relocation Disables option --enable-auto-relocation.
--enable-r8 Runs R8 over the final shadowed JAR.
--no-enable-r8 Disables option --enable-r8.
--enable-kotlin-module-remapping Enables remapping of Kotlin module metadata files.
--no-enable-kotlin-module-remapping Disables option --enable-kotlin-module-remapping.
--fail-on-duplicate-entries Fails build if the ZIP entries in the shadowed JAR are duplicate.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,10 +668,8 @@ class CachingTest : BasePluginTest() {
implementation project(':client')
}
$shadowJarTask {
minimize {
r8 {
proguardRuleFiles.from(file("r8-rules.pro"))
}
r8 {
proguardRuleFiles.from(file("r8-rules.pro"))
}
}
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ class JavaPluginsTest : BasePluginTest() {
"--no-add-multi-release-attribute Disables option --add-multi-release-attribute.",
"--enable-auto-relocation Enables auto relocation of packages in the dependencies.",
"--no-enable-auto-relocation Disables option --enable-auto-relocation.",
"--enable-r8 Runs R8 over the final shadowed JAR.",
"--no-enable-r8 Disables option --enable-r8.",
"--enable-kotlin-module-remapping Enables remapping of Kotlin module metadata files.",
"--no-enable-kotlin-module-remapping Disables option --enable-kotlin-module-remapping.",
"--fail-on-duplicate-entries Fails build if the ZIP entries in the shadowed JAR are duplicate.",
Expand Down Expand Up @@ -822,9 +824,7 @@ class JavaPluginsTest : BasePluginTest() {
"""
${getDefaultProjectBuildScript(applyShadowPlugin = false)}
def $customShadowJar = tasks.register('$customShadowJar', ${ShadowJar::class.java.name}) {
minimize {
r8 {}
}
r8 {}
}
"""
.trimIndent()
Expand All @@ -834,7 +834,7 @@ class JavaPluginsTest : BasePluginTest() {

assertThat(result.output)
.contains(
"R8 minimization requires a non-empty R8 classpath. Apply the Shadow plugin or configure the shadowR8 configuration."
"R8 post-processing requires a non-empty R8 classpath. Apply the Shadow plugin or configure the shadowR8 configuration."
)
}

Expand Down
Loading