Skip to content

Minimizing

Shadow can automatically remove all JARs and classes of dependencies that are not used by the project, thereby minimizing the resulting shadowed JAR.

tasks.shadowJar {
  minimize()
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize()
}

A dependency can be excluded from the minimization process, thereby forcing its inclusion the shadow JAR. This is useful when the dependency analyzer cannot find the usage of a class programmatically, for example if the class is loaded dynamically via Class.forName(String). Each of the group, name and version fields separated by : of a dependency is interpreted as a regular expression.

tasks.shadowJar {
  minimize {
    exclude(dependency("org.scala-lang:.*:.*"))
  }
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    exclude(dependency('org.scala-lang:.*:.*'))
  }
}

Dependencies scoped as api will be automatically excluded from minimization and used as “entry points” on minimization.

Similar to ShadowJar.dependencies, projects can also be excluded.

tasks.shadowJar {
  minimize {
    exclude(project(":api"))
  }
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    exclude(project(":api"))
  }
}

When excluding a project, all dependencies of the excluded project are automatically excluded from minimization as well.

Minimizing with R8

Shadow can also run 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.

The default R8 configuration only shrinks unused code. It disables name minification and optimization.

repositories {
  google()
}

tasks.shadowJar {
  minimize {
    r8 {
      // Optional extra configuration
      keepRules.add("-keep class com.example.ReflectiveApi { *; }")
      keepRuleFiles.from(layout.projectDirectory.file("r8-rules.pro"))
    }
  }
}
repositories {
  google()
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    r8 {
      // Optional extra configuration
      keepRules.add('-keep class com.example.ReflectiveApi { *; }')
      keepRuleFiles.from(layout.projectDirectory.file('r8-rules.pro'))
    }
  }
}

Shadow resolves R8 from the shadowR8 configuration. The default dependency is com.android.tools:r8, which is published by Google Maven rather than Maven Central. Add google() to your repositories or override the dependency:

dependencies {
  shadowR8("com.android.tools:r8:9.1.31")
}
dependencies {
  shadowR8 'com.android.tools:r8:9.1.31'
}

Advanced R8 command line arguments can be added with args. Replacing the default args value removes Shadow’s default command line arguments, so prefer the helper functions for common obfuscation and optimization toggles. These helpers are independent and can be used together.

For example, to downgrade R8 warnings to info:

repositories {
  google()
}

tasks.shadowJar {
  minimize {
    r8 {
      args.addAll(listOf("--map-diagnostics", "warning", "info"))
    }
  }
}
repositories {
  google()
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    r8 {
      args.addAll(['--map-diagnostics', 'warning', 'info'])
    }
  }
}

To enable name obfuscation:

repositories {
  google()
}

tasks.shadowJar {
  minimize {
    r8 {
      enableObfuscation()
    }
  }
}
repositories {
  google()
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    r8 {
      enableObfuscation()
    }
  }
}

To enable optimization:

repositories {
  google()
}

tasks.shadowJar {
  minimize {
    r8 {
      enableOptimization()
    }
  }
}
repositories {
  google()
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    r8 {
      enableOptimization()
    }
  }
}

To enable both:

repositories {
  google()
}

tasks.shadowJar {
  minimize {
    r8 {
      enableObfuscation()
      enableOptimization()
    }
  }
}
repositories {
  google()
}

tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
  minimize {
    r8 {
      enableObfuscation()
      enableOptimization()
    }
  }
}