### Install MkDocs Dependencies Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Installs the necessary Python packages for building and previewing the documentation website. ```bash pip install mkdocs mkdocs-material ``` -------------------------------- ### Shadow Jar Configuration (8.x) Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Example of Shadow Jar configuration in version 8.x, including enabling relocation, setting duplicate strategy, and merging service files. ```gradle tasks.shadowJar { isEnableRelocation = true duplicatesStrategy = DuplicatesStrategy.EXCLUDE mergeServiceFiles() from("foo.jar") } ``` -------------------------------- ### Configure Resource Transformers with Duplicates Strategy (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Example showing how to make Resource Transformers work with duplicates strategy by setting the default to INCLUDE/WARN, applying transformers, and then excluding specific files. ```kotlin tasks.shadowJar { // Step 1. duplicatesStrategy = DuplicatesStrategy.INCLUDE // Or WARN. // Step 2. mergeServiceFiles() // Step 3. Using `filesNotMatching`: filesNotMatching("META-INF/services/**") { duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or FAIL. } // Step 3. Using `PreserveFirstFoundResourceTransformer`: transform() { resources.add("META-INF/foo/**") // Or something else where the first occurrence should be preserved. } } ``` -------------------------------- ### Configure Shadow for Kotlin JVM Plugin Source: https://github.com/gradleup/shadow/blob/main/docs/kotlin-plugins/README.md Example of configuring the shadow plugin for a Kotlin JVM project. This setup works similarly to Java projects. ```kotlin plugins { id("org.jetbrains.kotlin.jvm") id("com.gradleup.shadow") } dependencies { implementation("io.ktor:ktor-client-okhttp:3.1.0") } ``` ```groovy plugins { id 'org.jetbrains.kotlin.jvm' id 'com.gradleup.shadow' } dependencies { implementation 'io.ktor:ktor-client-okhttp:3.1.0' } ``` -------------------------------- ### Configure Shadow for Kotlin Multiplatform Plugin Source: https://github.com/gradleup/shadow/blob/main/docs/kotlin-plugins/README.md Example of configuring the shadow plugin for a Kotlin Multiplatform project. This includes setting the main class for the shadowed JAR. ```kotlin plugins { id("org.jetbrains.kotlin.multiplatform") id("com.gradleup.shadow") } val ktorVersion = "3.1.0" kotlin { @Suppress("OPT_IN_USAGE") jvm().mainRun { // Optionally, set the main class for `runJvm`. mainClass = "myapp.MainKt" } sourceSets { val commonMain by getting { dependencies { implementation("io.ktor:ktor-client-core:$ktorVersion") } } val jvmMain by getting { dependencies { implementation("io.ktor:ktor-client-okhttp:$ktorVersion") } } } } // TODO: Gradle doesn't generate accessors for this use case, so we can't call `tasks.shadowJar` directly like the other examples. tasks.named("shadowJar") { manifest { // Optionally, set the main class for the shadowed JAR. attributes["Main-Class"] = "com.example.MainKt" } } ``` ```groovy plugins { id 'org.jetbrains.kotlin.multiplatform' id 'com.gradleup.shadow' } def ktorVersion = "3.1.0" kotlin { jvm().mainRun { // Optionally, set the main class for `runJvm`. it.mainClass.set('myapp.MainKt') } sourceSets { commonMain { dependencies { implementation "io.ktor:ktor-client-core:$ktorVersion" } } jvmMain { dependencies { implementation "io.ktor:ktor-client-okhttp:$ktorVersion" } } } } tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { manifest { // Optionally, set the main class for the shadowed JAR. attributes 'Main-Class': 'com.example.MainKt' } } ``` -------------------------------- ### Publishing with Maven-Publish Plugin (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/publishing/README.md Configure the maven-publish plugin to publish the shadow component. This setup is automatic when both plugins are present. ```kotlin plugins { java `maven-publish` id("com.gradleup.shadow") } publishing { publications { create("shadow") { from(components["shadow"]) } } repositories { maven("https://repo.myorg.com") } } ``` -------------------------------- ### Publishing with Maven-Publish Plugin (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/publishing/README.md Configure the maven-publish plugin to publish the shadow component. This setup is automatic when both plugins are present. ```groovy plugins { id 'java' id 'maven-publish' id 'com.gradleup.shadow' } publishing { publications { shadow(MavenPublication) { from components.shadow } } repositories { maven { url = 'https://repo.myorg.com' } } } ``` -------------------------------- ### Shadow Jar Configuration (9.x) Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Example of Shadow Jar configuration in version 9.x, demonstrating renamed properties and updated duplicate handling for merging service files. Note the change in `duplicatesStrategy` and the introduction of `failOnDuplicateEntries`. ```gradle tasks.shadowJar { // `isEnableRelocation` has been renamed to `enableAutoRelocation`. enableAutoRelocation = true // If you want to make `mergeServiceFiles` or most resource transformers work, you should set the `duplicatesStrategy` to `INCLUDE`. // Because `EXCLUDE` will exclude extra service files to be merged. duplicatesStrategy = DuplicatesStrategy.INCLUDE mergeServiceFiles() // Optionally, you can enable the new `failOnDuplicateEntries` property to fail the build if there are duplicate entries. failOnDuplicateEntries = true // If you want to keep the `foo.jar` as-is (zipped), you can use the `from` method directly. This is different from the previous. from("foo.jar") // If you want to unzip the `foo.jar` before processing, you can use `zipTree` to unzip it. from(zipTree("foo.jar")) } ``` -------------------------------- ### Preview Documentation Locally Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Builds and serves the documentation website locally for preview. Navigate to http://127.0.0.1:8000/ to view. ```bash mkdocs serve ``` -------------------------------- ### View ShadowJar Task Help Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Run this command to view more information about the `ShadowJar` task, including its available options and configuration details. ```sh ./gradlew -q help --task shadowJar ``` -------------------------------- ### Apply Code Formatting Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Ensures consistent code formatting using Spotless. Run this before submitting changes. ```bash ./gradlew spotlessApply ``` -------------------------------- ### Run All Test Suites Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Executes all configured test suites (unit, documentation, and functional) before submitting changes. ```bash ./gradlew test documentTest functionalTest ``` -------------------------------- ### Filter Relocation with Exclude and Include in Groovy Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Configure relocation for 'junit.textui' to 'a', excluding 'junit.textui.TestRunner'. Also, relocate 'junit.framework' to 'b', including only classes starting with 'junit.framework.Test*'. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { relocate('junit.textui', 'a') { exclude 'junit.textui.TestRunner' } relocate('junit.framework', 'b') { include 'junit.framework.Test*' } } ``` -------------------------------- ### Filter Relocation with Exclude and Include in Kotlin Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Configure relocation for 'junit.textui' to 'a', excluding 'junit.textui.TestRunner'. Also, relocate 'junit.framework' to 'b', including only classes starting with 'junit.framework.Test*'. ```kotlin tasks.shadowJar { relocate("junit.textui", "a") { exclude("junit.textui.TestRunner") } relocate("junit.framework", "b") { include("junit.framework.Test*") } } ``` -------------------------------- ### Build Static Documentation Site Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Builds the static HTML files for the documentation website. These files can be deployed to any web server. ```bash mkdocs build ``` -------------------------------- ### Apply Application and Shadow Plugins (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md Apply the application and shadow plugins and set the main class for your application. ```kotlin plugins { application id("com.gradleup.shadow") } application { mainClass = "myapp.Main" } ``` -------------------------------- ### Configure Shadow Distribution Files (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md This Groovy snippet demonstrates how to configure the Shadow plugin to include extra files in the distribution. It includes adding files from a specific directory and placing them into a subdirectory within the distribution. ```groovy plugins { id 'application' id 'com.gradleup.shadow' } application { mainClass = 'myapp.Main' // Optionally, you can include `some/dir` files in the distribution like this: applicationDistribution.from('some/dir') { include '*.txt' } } // `shadow` is the name of the distribution created by Shadow plugin distributions.named('shadow') { // Optionally, you can add more files into extra directory in the distribution like this: contents.from('extra/echo.sh') { into 'extra' } } tasks.named('installShadowDist', Sync) { // Configure the install task if needed. } tasks.named('startShadowScripts', CreateStartScripts) { // Configure the start scripts task if needed. } tasks.named('shadowDistZip', Zip) { // Configure the zip distribution task if needed. } tasks.named('shadowDistTar', Tar) { // Configure the tar distribution task if needed. } ``` -------------------------------- ### Configure Shadow Distribution Files (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md Use this Kotlin snippet to configure the Shadow plugin to include additional files in the distribution. It shows how to add files from a directory and specify a subdirectory within the distribution. ```kotlin plugins { application id("com.gradleup.shadow") } application { mainClass = "myapp.Main" // Optionally, you can include `some/dir` files in the distribution like this: applicationDistribution.from("some/dir") { include("*.txt") } } // `shadow` is the name of the distribution created by Shadow plugin distributions.shadow { // Optionally, you can add more files into extra directory in the distribution like this: contents.from("extra/echo.sh") { into("extra") } } tasks.installShadowDist { // Configure the install task if needed. } tasks.startShadowScripts { // Configure the start scripts task if needed. } tasks.shadowDistZip { // Configure the zip distribution task if needed. } tasks.shadowDistTar { // Configure the tar distribution task if needed. } ``` -------------------------------- ### Apply Application and Shadow Plugins (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md Apply the application and shadow plugins and set the main class for your application. ```groovy plugins { id 'application' id 'com.gradleup.shadow' } application { mainClass = 'myapp.Main' } ``` -------------------------------- ### ShadowJar: Automatic Unzipping via Implementation Dependency Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Illustrates how ShadowJar automatically unzips files when they are added as an implementation dependency. This simplifies the process of including and processing contents of zip archives. ```gradle dependencies { // Add the files to `implementation` configuration, Shadow will unzip them automatically. implementation(files('path/to/your/file.zip')) } ``` -------------------------------- ### Build Project Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Runs compilation, tests, and standard verification tasks. This provides a comprehensive check of the project. ```bash ./gradlew build ``` -------------------------------- ### Handling Duplicate Resources with ShadowJar Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Demonstrates how to override the default duplicates strategy for specific files using `filesMatching`. This is useful when the default `INCLUDE` strategy needs to be adjusted for certain resources. ```gradle tasks.shadowJar { duplicatesStrategy = DuplicatesStrategy.INCLUDE filesMatching("**/*.txt") { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } } ``` -------------------------------- ### ShadowJar: Unzipping Files Before Processing Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Shows how to ensure files within a zip archive are unzipped before being processed by the `ShadowJar.from` configuration. This is achieved by using `zipTree`. ```gradle tasks.shadowJar { // Unzip the files before pass them to `from` by using `zipTree`. from(zipTree(files('path/to/your/file.zip'))) } ``` -------------------------------- ### Combine Duplicates Strategy with Resource Transformers (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Demonstrates setting the default duplicates strategy and then merging service files. Note that the default strategy takes precedence over transformers. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { duplicatesStrategy = DuplicatesStrategy.EXCLUDE // The default strategy. mergeServiceFiles() } ``` -------------------------------- ### Run Documentation Tests Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Tests code snippets within the docs/ directory. This helps ensure documentation accuracy. ```bash ./gradlew documentTest ``` -------------------------------- ### Configure Shadow Plugin with Maven Publish (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/publishing/README.md Illustrates the configuration of the Shadow plugin with the Maven Publish plugin using Groovy. It covers dependency declarations for bundling, runtime inclusion, and complete exclusion from the shadowed JAR and POM. ```groovy plugins { id 'java' id 'maven-publish' id 'com.gradleup.shadow' } def retrofitVersion = '2.12.0' dependencies { // This will be bundled in the shadowed JAR and not declared in the POM. implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" // This will be excluded from the shadowed JAR but declared as a runtime dependency in `META-INF/MANIFEST.MF` // file's `Class-Path` entry, and also in the POM file. shadow "com.squareup.retrofit2:converter-java8:$retrofitVersion" // This will be excluded from the shadowed JAR and not declared in the POM or `META-INF/MANIFEST.MF`. compileOnly "com.squareup.retrofit2:converter-scalars:$retrofitVersion" } publishing { publications { shadow(MavenPublication) { from components.shadow // Optionally, you can add extra dependencies to the POM file like the following: pom.withXml { xml -> def dependenciesNode = xml.asNode().get('dependencies') ?: xml.asNode().appendNode('dependencies') def node = dependenciesNode.appendNode('dependency') node.appendNode('groupId', 'com.squareup.retrofit2') node.appendNode('artifactId', 'converter-gson') node.appendNode('version', retrofitVersion) node.appendNode('scope', 'runtime') } } } repositories { maven { url = 'https://repo.myorg.com' } } } ``` -------------------------------- ### Running an Executable Shadow JAR Source: https://github.com/gradleup/shadow/blob/main/docs/README.md This command executes a Shadow JAR. Ensure the JRE is available on the target system. ```sh java -jar application-shadow.jar ``` -------------------------------- ### Tag the release version Source: https://github.com/gradleup/shadow/blob/main/RELEASING.md Create an annotated Git tag for the specific release version. ```sh git tag -am "Version X.Y.Z" X.Y.Z ``` -------------------------------- ### Basic Kotlin ResourceTransformer Implementation Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Demonstrates how to create a basic custom ResourceTransformer in Kotlin. This transformer can be applied to the shadowJar task. ```kotlin import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext import org.apache.tools.zip.ZipOutputStream import org.gradle.api.file.FileTreeElement class MyTransformer : ResourceTransformer { override fun canTransformResource(element: FileTreeElement): Boolean = true override fun transform(context: TransformerContext) {} override fun hasTransformedResource(): Boolean = true override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {} } tasks.shadowJar { transform() } ``` -------------------------------- ### Configure Service Descriptor File Location (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Override the default META-INF/services path to merge descriptor files from a different location using `mergeServiceFiles { path = ... }` or `transform(ServiceFileTransformer) { path = ... }`. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { // Short syntax. mergeServiceFiles { path = 'META-INF/custom' } // Full syntax. transform(com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer) { path = 'META-INF/custom' } } ``` -------------------------------- ### Run Unit Tests Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Executes the project's unit tests. Ensure all tests pass before submitting changes. ```bash ./gradlew test ``` -------------------------------- ### Configure Shadow Plugin with Maven Publish (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/publishing/README.md Demonstrates how to configure the Shadow plugin with the Maven Publish plugin in Kotlin. It shows how to declare dependencies that are bundled, excluded from the shadowed JAR but declared as runtime, and completely excluded. ```kotlin plugins { java `maven-publish` id("com.gradleup.shadow") } val retrofitVersion = "2.12.0" dependencies { // This will be bundled in the shadowed JAR and not declared in the POM. implementation("com.squareup.retrofit2:retrofit:$retrofitVersion") // This will be excluded from the shadowed JAR but declared as a runtime dependency in `META-INF/MANIFEST.MF` // file's `Class-Path` entry, and also in the POM file. shadow("com.squareup.retrofit2:converter-java8:$retrofitVersion") // This will be excluded from the shadowed JAR and not declared in the POM or `META-INF/MANIFEST.MF`. compileOnly("com.squareup.retrofit2:converter-scalars:$retrofitVersion") } publishing { publications { create("shadow") { from(components["shadow"]) // Optionally, you can add extra dependencies to the POM file like the following: pom.withXml { val dependenciesNode = asNode().get("dependencies") ?: asNode().appendNode("dependencies") val node = (dependenciesNode as groovy.util.Node).appendNode("dependency") node.appendNode("groupId", "com.squareup.retrofit2") node.appendNode("artifactId", "converter-gson") node.appendNode("version", retrofitVersion) node.appendNode("scope", "runtime") } } } repositories { maven("https://repo.myorg.com") } } ``` -------------------------------- ### Enable Automatic Dependency Relocation (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Use this snippet to enable automatic package relocation for all dependencies and set a custom prefix. This is configured within the `shadowJar` task. ```kotlin tasks.shadowJar { enableAutoRelocation = true relocationPrefix = "myapp" } ``` -------------------------------- ### Configure ApacheLicenseResourceTransformer with Include/Exclude Patterns (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Configure the `shadowJar` task to use a specific resource transformer and apply `include` and `exclude` patterns. This allows fine-grained control over which files are processed by the transformer. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { transform(com.github.jengelman.gradle.plugins.shadow.transformers.ApacheLicenseResourceTransformer) { include 'META-INF/LICENSE.*' exclude 'META-INF/LICENSE.log' } } ``` -------------------------------- ### Add Extra Files to ShadowJar (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/README.md Use the `from` method in Kotlin to copy files or directories into a specific location within the shadowed JAR. ```kotlin tasks.shadowJar { from("Foo") { // Copy Foo file into Bar/ in the shadowed JAR. into("Bar") } } ``` -------------------------------- ### Basic Groovy ResourceTransformer Implementation Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Shows how to implement a basic custom ResourceTransformer in Groovy. This transformer is then applied to the shadowJar task. ```groovy import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext import org.apache.tools.zip.ZipOutputStream import org.gradle.api.file.FileTreeElement class MyTransformer implements ResourceTransformer { @Override boolean canTransformResource(FileTreeElement element) { return true } @Override void transform(TransformerContext context) {} @Override boolean hasTransformedResource() { return true } @Override void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {} } tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { transform(MyTransformer) } ``` -------------------------------- ### Add Extra Files to ShadowJar (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/README.md Use the `from` method in Groovy to copy files or directories into a specific location within the shadowed JAR. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { from('Foo') { // Copy Foo file into Bar/ in the shadowed JAR. into('Bar') } } ``` -------------------------------- ### Combine Duplicates Strategy with Resource Transformers (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Demonstrates setting the default duplicates strategy and then merging service files. Note that the default strategy takes precedence over transformers. ```kotlin tasks.shadowJar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE // The default strategy. mergeServiceFiles() } ``` -------------------------------- ### Configure Service Descriptor File Location (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Override the default META-INF/services path to merge descriptor files from a different location using `mergeServiceFiles { path = ... }` or `transform() { path = ... }`. ```kotlin tasks.shadowJar { // Short syntax. mergeServiceFiles { path = "META-INF/custom" } // Full syntax. transform() { path = "META-INF/custom" } } ``` -------------------------------- ### Configure runShadow Task with Arguments (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md Configure the runShadow task to execute the shadowed JAR with specific arguments and set default JVM arguments. ```kotlin plugins { application id("com.gradleup.shadow") } application { mainClass = "myapp.Main" // Optionally, you can add default JVM arguments to the start scripts like this: applicationDefaultJvmArgs = listOf("--add-opens=java.base/java.lang=ALL-UNNAMED") } tasks.runShadow { args("foo") } ``` -------------------------------- ### Configure runShadow Task with Arguments (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/application-plugin/README.md Configure the runShadow task to execute the shadowed JAR with specific arguments and set default JVM arguments. ```groovy plugins { id 'application' id 'com.gradleup.shadow' } application { mainClass = 'myapp.Main' // Optionally, you can add default JVM arguments to the start scripts like this: applicationDefaultJvmArgs = ['--add-opens=java.base/java.lang=ALL-UNNAMED'] } tasks.named('runShadow', JavaExec) { args 'foo' } ``` -------------------------------- ### Configure ApacheLicenseResourceTransformer with Include/Exclude Patterns (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Use the `transform` method with a specific resource transformer and then apply `include` and `exclude` to filter resources. This is useful for selectively including or excluding files based on their paths. ```kotlin tasks.shadowJar { transform() { include("META-INF/LICENSE.*") exclude("META-INF/LICENSE.log") } } ``` -------------------------------- ### Configuring Kotlin ResourceTransformer with Closure Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Illustrates initializing a custom ResourceTransformer in Kotlin using its default constructor and then configuring it with a closure. An instantiated transformer can also be configured. ```kotlin import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext import org.apache.tools.zip.ZipOutputStream import org.gradle.api.file.FileTreeElement class MyTransformer(@get:Input var enabled: Boolean = false) : ResourceTransformer { override fun canTransformResource(element: FileTreeElement): Boolean = enabled override fun transform(context: TransformerContext) {} override fun hasTransformedResource(): Boolean = enabled override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {} } tasks.shadowJar { // Initialize with default constructor and configure with closure. transform() { enabled = true } // Or use the instantiated instance with closure. transform(MyTransformer(false)) { enabled = true } } ``` -------------------------------- ### Relocate Project Resources Only (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Configure the `shadowJar` task to relocate only project resources by setting the `configurations` list to empty, effectively excluding all dependencies. A specific relocation is then defined using the `relocate` method. ```kotlin tasks.shadowJar { // Empty configurations list will exclude all dependencies. configurations = emptyList() relocate("com.example", "shadow.com.example") } ``` -------------------------------- ### Relocate Project Resources Only (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Configure the `shadowJar` task to relocate only project resources by setting the `configurations` list to empty, effectively excluding all dependencies. A specific relocation is then defined using the `relocate` method. ```groovy tasks.named('shadowJar', com.github.jengelman.plugins.shadow.tasks.ShadowJar) { // Empty configurations list will exclude all dependencies. configurations = [] relocate 'com.example', 'shadow.com.example' } ``` -------------------------------- ### Relocate All Packages Except Specific Ones in Kotlin Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Relocate all packages to 'my/shadow/prefix', excluding 'META-INF/**' and 'junit/**'. This is achieved by specifying an empty string as the initial pattern. ```kotlin tasks.shadowJar { relocate("", "my/shadow/prefix") { exclude("META-INF/**") // Exclude all JUnit packages. exclude("junit/**") } } ``` -------------------------------- ### Inherit Manifest from Jar Task Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Demonstrates the recommended way to inherit the manifest from the `jar` task for a `shadowJar` task. The previous `inheritFrom` method is deprecated. ```kotlin tasks.shadowJar { // Before (deprecated): manifest.inheritFrom(tasks.jar.get().manifest) // After (recommended): manifest.from(tasks.jar.get().manifest) // Note: You don't need to inherit the manifest from `jar` task as it's done by default for the `shadowJar` task. // But if you want to inherit the manifest for your custom `ShadowJar` task, you still need to do it explicitly. } ``` -------------------------------- ### Configure Shadow Plugin for Groovy with Groovy DSL Source: https://github.com/gradleup/shadow/blob/main/docs/groovy-and-scala-plugins/README.md Apply the Shadow plugin and configure the shadowJar task to set the main class for Groovy projects using Groovy DSL. ```groovy plugins { id 'groovy' id 'com.gradleup.shadow' } tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { manifest { // Optionally, set the main class for the shadowed JAR. attributes 'Main-Class': 'com.example.Main' } } ``` -------------------------------- ### ShadowJar Command Line Options Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md These options can be passed to the `shadowJar` task to control its behavior, such as adding manifest attributes, enabling auto-relocation, handling duplicate entries, minimizing the JAR, and controlling task re-execution. ```bash --add-multi-release-attribute Adds the multi-release attribute to the manifest if any dependencies contain it. --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-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. --no-fail-on-duplicate-entries Disables option --fail-on-duplicate-entries. --main-class Main class attribute to add to manifest. --minimize-jar Minimizes the jar by removing unused classes. --no-minimize-jar Disables option --minimize-jar. --relocation-prefix Prefix used for auto relocation of packages in the dependencies. --rerun Causes the task to be re-run even if up-to-date. ``` -------------------------------- ### Run Functional Tests with Specific Gradle Version Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Verifies compatibility with a specific Gradle version. Useful for ensuring the plugin works with different Gradle releases. ```bash ./gradlew functionalTest -PtestGradleVersion=9.1.0 ``` -------------------------------- ### Enable Automatic Dependency Relocation (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Use this snippet to enable automatic package relocation for all dependencies and set a custom prefix. This is configured within the `shadowJar` task. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { enableAutoRelocation = true relocationPrefix = "myapp" } ``` -------------------------------- ### Relocate Packages in Kotlin Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Use this snippet to relocate all classes from 'junit.framework' to 'shadow.junit'. This is applied globally to all instances of the matched prefix. ```kotlin tasks.shadowJar { relocate("junit.framework", "shadow.junit") } ``` -------------------------------- ### Use Regex for Advanced Path Matching in Kotlin Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Relocate classes from 'org.foo' to 'a', including only those matching the regex pattern 'org/foo/.*Factory[0-9].*'. ```kotlin tasks.shadowJar { relocate("org.foo", "a") { include("%regex[org/foo/.*Factory[0-9].*]") } } ``` -------------------------------- ### Run Functional Tests Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Executes functional and integration tests for the plugin. This verifies the plugin's behavior in realistic scenarios. ```bash ./gradlew functionalTest ``` -------------------------------- ### Configure Shadow Plugin for Groovy with Kotlin DSL Source: https://github.com/gradleup/shadow/blob/main/docs/groovy-and-scala-plugins/README.md Apply the Shadow plugin and configure the shadowJar task to set the main class for Groovy projects using Kotlin DSL. ```kotlin plugins { groovy id("com.gradleup.shadow") } tasks.shadowJar { manifest { // Optionally, set the main class for the shadowed JAR. attributes["Main-Class"] = "com.example.Main" } } ``` -------------------------------- ### Combine Include and Exclude Filters (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/filtering/README.md Combine 'include' and 'exclude' methods in Kotlin to selectively include and exclude files. Excludes take precedence over includes. ```kotlin tasks.shadowJar { include("*.jar") include("*.properties") exclude("a2.properties") } ``` -------------------------------- ### Configuring Groovy ResourceTransformer with Closure Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Shows how to initialize a custom ResourceTransformer in Groovy using its default constructor and configure it with a closure. An instantiated transformer can also be configured. ```groovy import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext import org.apache.tools.zip.ZipOutputStream import org.gradle.api.file.FileTreeElement class MyTransformer implements ResourceTransformer { @Input boolean enabled MyTransformer(boolean enabled = false) { this.enabled = enabled } @Override boolean canTransformResource(FileTreeElement element) { return enabled } @Override void transform(TransformerContext context) {} @Override boolean hasTransformedResource() { return enabled } @Override void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {} } tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { // Initialize with default constructor and configure with closure. transform(MyTransformer) { enabled = true } // Or use the instantiated instance with closure. transform(new MyTransformer(false)) { enabled = true } } ``` -------------------------------- ### Shadow Jar Command Line Options Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Configure ShadowJar behavior using command-line flags. These options control features like auto-relocation, duplicate entry handling, JAR minimization, and task reruns. ```bash --enable-auto-relocation Enables auto relocation of packages in the dependencies. --no-enable-auto-relocation Disables option --enable-auto-relocation. --fail-on-duplicate-entries Fails build if the ZIP entries in the shadowed JAR are duplicate. --no-fail-on-duplicate-entries Disables option --fail-on-duplicate-entries. --minimize-jar Minimizes the jar by removing unused classes. --no-minimize-jar Disables option --minimize-jar. --relocation-prefix Prefix used for auto relocation of packages in the dependencies. --rerun Causes the task to be re-run even if up-to-date. ``` -------------------------------- ### Run Specific Unit Test Source: https://github.com/gradleup/shadow/blob/main/CONTRIBUTING.md Allows running a single unit test class for faster local development and debugging. ```bash ./gradlew test --tests "com.example.YourTestClass" ``` -------------------------------- ### Apply Shadow Plugin with Snapshot Version (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Configure buildscript to use snapshot versions of the Shadow plugin from a specific repository in Kotlin. This is for development or testing purposes. ```kotlin buildscript { repositories { mavenCentral() maven("https://central.sonatype.com/repository/maven-snapshots/") } dependencies { // You can get the latest snapshot version from `VERSION_NAME` declared in https://github.com/GradleUp/shadow/blob/main/gradle.properties classpath("com.gradleup.shadow:shadow-gradle-plugin:") } } // `apply plugin` stuff are used with `buildscript`. apply(plugin = "java") apply(plugin = "com.gradleup.shadow") ``` -------------------------------- ### Apply Shadow Plugin with Snapshot Version (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Configure buildscript to use snapshot versions of the Shadow plugin from a specific repository in Groovy. This is for development or testing purposes. ```groovy buildscript { repositories { mavenCentral() maven { url = 'https://central.sonatype.com/repository/maven-snapshots/' } } dependencies { // You can get the latest snapshot version from `VERSION_NAME` declared in https://github.com/GradleUp/shadow/blob/main/gradle.properties classpath 'com.gradleup.shadow:shadow-gradle-plugin:' } } // `apply plugin` stuff are used with `buildscript`. apply plugin: 'java' apply plugin: 'com.gradleup.shadow' ``` -------------------------------- ### Configure Duplicates Strategy for Shadow Jar (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Set the global duplicates strategy for the shadowJar task. Use `mergeServiceFiles()` to merge service files. Apply specific strategies to files matching or not matching certain patterns, or use `eachFile` for granular control. Optionally, enable `failOnDuplicateEntries`. ```Groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { // Step 1. duplicatesStrategy = DuplicatesStrategy.INCLUDE // Or WARN. // Step 2. mergeServiceFiles() // Step 3. Using `filesNotMatching`: filesNotMatching('META-INF/services/**') { duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or FAIL. } // Step 3. Using `PreserveFirstFoundResourceTransformer`: transform(com.github.jengelman.gradle.plugins.shadow.transformers.PreserveFirstFoundResourceTransformer) { resources.add('META-INF/foo/**') // Or something else where the first occurrence should be preserved. } } ``` ```Groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { // Step 1. duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Or FAIL. // Step 2. mergeServiceFiles() // Step 3. Using `filesMatching`: filesMatching('META-INF/services/**') { duplicatesStrategy = DuplicatesStrategy.INCLUDE // Or WARN. } // Step 3. Using `eachFile`: eachFile { if (it.path.startsWith('META-INF/services/')) { it.duplicatesStrategy = DuplicatesStrategy.INCLUDE // Or WARN. } } } ``` ```Groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { // Optional step. failOnDuplicateEntries = true } ``` -------------------------------- ### Create Custom ShadowJar Task with Project and Test Dependencies (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/custom-tasks/README.md Use this Groovy snippet to register a custom ShadowJar task that includes both main and test project outputs along with their runtime dependencies. Configure the archive classifier and manifest attributes as needed. ```groovy def testShadowJar = tasks.register('testShadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { description = 'Create a combined JAR of project and test dependencies' archiveClassifier = 'test' from sourceSets.named('test').map { it.output } configurations = project.configurations.named('testRuntimeClasspath').map { [it] } manifest { // Optionally, set the main class for the JAR. attributes 'Main-Class': 'test.Main' // You can also set other attributes here. } } // Optionally, make the `assemble` task depend on the new task. tasks.named('assemble') { dependsOn testShadowJar } ``` -------------------------------- ### Combine Include and Exclude Filters (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/filtering/README.md Combine 'include' and 'exclude' methods in Groovy to selectively include and exclude files. Excludes take precedence over includes. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { include '*.jar' include '*.properties' exclude 'a2.properties' } ``` -------------------------------- ### Shadow Plugin Configuration (Version 7.0.0) Source: https://github.com/gradleup/shadow/blob/main/docs/changes/README.md Configure the Shadow plugin using the buildscript classpath for Gradle 7.0+. Ensure to update the classpath dependency if you are explicitly declaring it. ```gradle buildscript { repositories { gradlePluginPortal() } dependencies { classpath "gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0" } } apply plugin: "com.gradleup.shadow" ``` -------------------------------- ### Use Regex for Advanced Path Matching in Groovy Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Relocate classes from 'org.foo' to 'a', including only those matching the regex pattern 'org/foo/.*Factory[0-9].*'. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { relocate('org.foo', 'a') { include '%regex[org/foo/.*Factory[0-9].*]' } } ``` -------------------------------- ### Enable Minimization in Shadow JAR Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/minimizing/README.md Enable the automatic minimization of unused dependencies for the shadowJar task. ```kotlin tasks.shadowJar { minimize() } ``` ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { minimize() } ``` -------------------------------- ### Relocate All Packages Except Specific Ones in Groovy Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Relocate all packages to 'my/shadow/prefix', excluding 'META-INF/**' and 'junit/**'. This is achieved by specifying an empty string as the initial pattern. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { relocate('', 'my/shadow/prefix') { exclude 'META-INF/**' // Exclude all JUnit packages. exclude 'junit/**' } } ``` -------------------------------- ### Create Custom ShadowJar Task with Project and Test Dependencies (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/custom-tasks/README.md Use this Kotlin snippet to register a custom ShadowJar task that includes both main and test project outputs along with their runtime dependencies. Configure the archive classifier and manifest attributes as needed. ```kotlin val testShadowJar by tasks.registering(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) { description = "Create a combined JAR of project and test dependencies" archiveClassifier = "test" from(sourceSets.test.map { it.output }) configurations = project.configurations.testRuntimeClasspath.map { listOf(it) } manifest { // Optionally, set the main class for the JAR. attributes(mapOf("Main-Class" to "test.Main")) // You can also set other attributes here. } } // Optionally, make the `assemble` task depend on the new task. tasks.assemble { dependsOn(testShadowJar) } ``` -------------------------------- ### Declare Runtime Dependencies with Shadow Configuration Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/README.md Adds dependencies to the 'shadow' configuration, which are not bundled into the output JAR but are required for runtime. These are automatically configured as RUNTIME scope dependencies in the POM file by the maven-publish plugin. ```kotlin dependencies { shadow("junit:junit:3.8.2") } ``` ```groovy dependencies { shadow 'junit:junit:3.8.2' } ``` -------------------------------- ### Relocate Packages in Groovy Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/relocation/README.md Use this snippet to relocate all classes from 'junit.framework' to 'shadow.junit'. This is applied globally to all instances of the matched prefix. ```groovy tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { relocate 'junit.framework', 'shadow.junit' } ``` -------------------------------- ### Configure Shadow Plugin for Scala with Kotlin DSL Source: https://github.com/gradleup/shadow/blob/main/docs/groovy-and-scala-plugins/README.md Apply the Shadow plugin and configure the shadowJar task to set the main class for Scala projects using Kotlin DSL. ```kotlin plugins { scala id("com.gradleup.shadow") } tasks.shadowJar { manifest { // Optionally, set the main class for the shadowed JAR. attributes["Main-Class"] = "com.example.Main" } } ``` -------------------------------- ### Configure Shadowed JAR as Default Artifact (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/multi-project/README.md In the shadowed project, reconfigure 'apiElements' and 'runtimeElements' to publish the shadowed JAR as the default artifact using Groovy. ```groovy plugins { id 'java-library' id 'com.gradleup.shadow' } configurations { apiElements { outgoing.artifacts.clear() outgoing.variants.clear() outgoing.artifact(tasks.named('shadowJar')) } runtimeElements { outgoing.artifacts.clear() outgoing.variants.clear() outgoing.artifact(tasks.named('shadowJar')) } } ``` -------------------------------- ### Configure Reproducible JARs in Kotlin Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/reproducible-builds/README.md Use this Kotlin script to configure archive tasks for reproducible builds. It disables file timestamp preservation, enables reproducible file order, and sets consistent Unix file permissions for files and directories. ```kotlin import java.nio.file.Files import java.nio.file.attribute.PosixFilePermission tasks.withType().configureEach { isPreserveFileTimestamps = false isReproducibleFileOrder = true eachFile { permissions { val isExec = Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE) unix(if (isExec) "755" else "644") } } dirPermissions { unix("755") } } ``` -------------------------------- ### Embedding Non-JAR Dependencies (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/dependencies/README.md Use a custom configuration and `tasks.shadowJar { from(nonJar) }` to embed non-JAR files. Ensure the custom configuration extends `compileClasspath` if compile-time availability is needed. ```kotlin val nonJar by configurations.creating // This is necessary to make the dependencies in `nonJar` available at compile time. // If you don't need that, you can skip this step. configurations.named("compileClasspath") { extendsFrom(nonJar) } dependencies { nonJar("org.graalvm.js:js-community:24.2.2") nonJar("io.github.ganadist.sqlite4java:libsqlite4java-osx-aarch64:1.0.392") // If you add a real JAR file into the new `nonJar` configuration, it will be included as-is. Different from `implementation`. nonJar(files("foo.jar")) } tasks.shadowJar { from(nonJar) } ``` -------------------------------- ### Apply Shadow Plugin via Buildscript Classpath (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Add the Shadow plugin to the buildscript classpath and apply it in a Groovy build script. This method is useful for older Gradle versions or specific configurations. ```groovy buildscript { repositories { mavenCentral() gradlePluginPortal() } dependencies { classpath 'com.gradleup.shadow:shadow-gradle-plugin:' } } // `apply plugin` stuff are used with `buildscript`. apply plugin: 'java' apply plugin: 'com.gradleup.shadow' ``` -------------------------------- ### Configure Shadow Plugin for Scala with Groovy DSL Source: https://github.com/gradleup/shadow/blob/main/docs/groovy-and-scala-plugins/README.md Apply the Shadow plugin and configure the shadowJar task to set the main class for Scala projects using Groovy DSL. ```groovy plugins { id 'scala' id 'com.gradleup.shadow' } tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { manifest { // Optionally, set the main class for the shadowed JAR. attributes 'Main-Class': 'com.example.Main' } } ``` -------------------------------- ### Apply Shadow Plugin using Plugins Block (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Apply the Shadow plugin using the plugins block in a Groovy build script. Ensure you replace '' with the actual plugin version. ```groovy plugins { id 'java' id 'com.gradleup.shadow' version '' } ``` -------------------------------- ### Commit changes for release preparation Source: https://github.com/gradleup/shadow/blob/main/RELEASING.md Commit all staged changes to prepare for a new release version. ```sh git commit -am "Prepare version X.Y.Z" ``` -------------------------------- ### Merge Service Descriptor Files (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/configuration/merging/README.md Use the short syntax `mergeServiceFiles()` or the full syntax `transform()` to merge service descriptor files in META-INF/services. ```kotlin tasks.shadowJar { // Short syntax. mergeServiceFiles() // Full syntax. transform() } ``` -------------------------------- ### Depend on Shadow Jar from Another Project (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/multi-project/README.md Declare a dependency on the 'shadow' configuration of a shadowed project in Groovy. ```groovy dependencies { implementation project(path: ':api', configuration: 'shadow') } ``` -------------------------------- ### Consume Shadowed JAR as Default (Groovy) Source: https://github.com/gradleup/shadow/blob/main/docs/multi-project/README.md Consuming projects can depend on the shadowed project without specifying the 'shadow' configuration when using Groovy. ```groovy dependencies { implementation project(':api') } ``` -------------------------------- ### Apply Shadow Plugin using Plugins Block (Kotlin) Source: https://github.com/gradleup/shadow/blob/main/docs/getting-started/README.md Apply the Shadow plugin using the plugins block in a Kotlin build script. Ensure you replace '' with the actual plugin version. ```kotlin plugins { java id("com.gradleup.shadow") version "" } ```