Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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: 2 additions & 1 deletion api/shadow.api
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks

public class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction : org/gradle/api/internal/file/copy/CopyAction {
public static final field Companion Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$Companion;
public fun <init> (Ljava/io/File;Lkotlin/jvm/functions/Function1;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ZZLjava/lang/String;)V
public fun <init> (Ljava/io/File;Lkotlin/jvm/functions/Function1;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ZZZLjava/lang/String;)V
public fun execute (Lorg/gradle/api/internal/file/copy/CopyActionProcessingStream;)Lorg/gradle/api/tasks/WorkResult;
}

Expand All @@ -228,6 +228,7 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar
public fun getDependencyFilter ()Lorg/gradle/api/provider/Property;
public fun getDuplicatesStrategy ()Lorg/gradle/api/file/DuplicatesStrategy;
public fun getEnableAutoRelocation ()Lorg/gradle/api/provider/Property;
public fun getEnableKotlinModuleRelocation ()Lorg/gradle/api/provider/Property;
public fun getExcludes ()Ljava/util/Set;
public fun getFailOnDuplicateEntries ()Lorg/gradle/api/provider/Property;
public fun getIncludedDependencies ()Lorg/gradle/api/file/ConfigurableFileCollection;
Expand Down
7 changes: 7 additions & 0 deletions docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
- Add new merge strategy `Fail` to `PropertiesFileTransformer`. ([#1856](https://github.com/GradleUp/shadow/pull/1856))
- Add `FindResourceInClasspath` task to help with debugging issues with merged duplicate resources. ([#1860](https://github.com/GradleUp/shadow/pull/1860))
- Add `MergeLicenseResourceTransformer`. ([#1858](https://github.com/GradleUp/shadow/pull/1858))
- Support disabling relocation of Kotlin module metadata. ([#1875](https://github.com/GradleUp/shadow/pull/1875))
```kotlin
tasks.shadowJar {
// Disable relocation of Kotlin module metadata (`.kotlin_module`) files. This is enabled by default.
enableKotlinModuleRelocation = false
}
```

### Changed

Expand Down
24 changes: 13 additions & 11 deletions docs/getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,19 @@ build script. Passing property values on the command line is particularly helpfu
Here are the options that can be passed to the `shadowJar`:

```
--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.
--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.
--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-relocation Enables relocation of Kotlin module metadata files.
--no-enable-kotlin-module-relocation Disables option --enable-kotlin-module-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.
--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.
```

Also, you can view more information about the [`ShadowJar`][ShadowJar] task by running the following command:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,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-kotlin-module-relocation Enables relocation of Kotlin module metadata files.",
"--no-enable-kotlin-module-relocation Disables option --enable-kotlin-module-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",
"--main-class Main class attribute to add to manifest.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,12 +603,14 @@ class RelocationTest : BasePluginTest() {
@Issue(
"https://github.com/GradleUp/shadow/issues/843",
)
@Test
@OptIn(UnstableMetadataApi::class)
fun relocateKotlinModuleFiles() {
@ParameterizedTest
@ValueSource(booleans = [false, true])
fun relocateKotlinModuleFiles(enableKotlinModuleRelocation: Boolean) {
val originalModuleFilePath = "META-INF/kotlin-stdlib.kotlin_module"
val originalModuleFileBytes = requireResourceAsPath(originalModuleFilePath).readBytes()
val stdlibJar = buildJar("stdlib.jar") {
insert(originalModuleFilePath, requireResourceAsPath(originalModuleFilePath).readBytes())
insert(originalModuleFilePath, originalModuleFileBytes)
}
projectScript.appendText(
"""
Expand All @@ -617,18 +619,31 @@ class RelocationTest : BasePluginTest() {
}
$shadowJarTask {
relocate('kotlin', 'my.kotlin')
enableKotlinModuleRelocation = $enableKotlinModuleRelocation
}
""".trimIndent(),
)

runWithSuccess(shadowJarPath)

val relocatedModuleFilePath = "META-INF/kotlin-stdlib.shadow.kotlin_module"
assertThat(outputShadowedJar).useAll {
containsOnly(
relocatedModuleFilePath,
*manifestEntries,
)

if (enableKotlinModuleRelocation) {
assertThat(outputShadowedJar).useAll {
containsOnly(
relocatedModuleFilePath,
*manifestEntries,
)
}
} else {
assertThat(outputShadowedJar).useAll {
containsOnly(
originalModuleFilePath,
*manifestEntries,
)
}
assertThat(outputShadowedJar.use { it.getBytes(originalModuleFilePath) }).isEqualTo(originalModuleFileBytes)
return
}

val originalModule = KotlinModuleMetadata.read(requireResourceAsStream(originalModuleFilePath).readBytes())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public open class ShadowCopyAction(
private val transformers: Set<ResourceTransformer>,
private val relocators: Set<Relocator>,
private val unusedClasses: Set<String>,
private val enableKotlinModuleRelocation: Boolean,
private val preserveFileTimestamps: Boolean,
private val failOnDuplicateEntries: Boolean,
private val encoding: String?,
Expand Down Expand Up @@ -174,7 +175,7 @@ public open class ShadowCopyAction(
}
}
path.endsWith(".kotlin_module") -> {
if (relocators.isEmpty()) {
if (relocators.isEmpty() || !enableKotlinModuleRelocation) {
fileDetails.writeToZip(path)
} else {
Comment on lines 176 to 179
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to expose the transform step for .kotlin_module files.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I see - the current change just disables remapping, but still does not trigger generic transformer. It would be nice to add a support for custom .kotlin_module transformer.

Copy link
Member Author

@Goooler Goooler Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a new issue: if the relocators is not empty, remapKotlinModule will be called first. Should we pass the relocated module file to transformers? I believe what you want here is passing the original module file to your custom transformer, and doing nothing from Shadow side. Just like

else -> {
val relocated = relocators.relocatePath(path)
if (transform(fileDetails, relocated)) return
fileDetails.writeToZip(relocated)
}

Copy link
Member Author

@Goooler Goooler Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

276692a

Disabling the newly added flag should align the behaviors with 8.x versions. Are you fine with the new flag?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, should be fine

fileDetails.remapKotlinModule()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ public abstract class ShadowJar : Jar() {
@get:Option(option = "enable-auto-relocation", description = "Enables auto relocation of packages in the dependencies.")
public open val enableAutoRelocation: Property<Boolean> = objectFactory.property(false)

/**
* Enables relocation of Kotlin module metadata (`.kotlin_module`) files.
*
* Defaults to `true`.
*/
@get:Input
@get:Option(option = "enable-kotlin-module-relocation", description = "Enables relocation of Kotlin module metadata files.")
public open val enableKotlinModuleRelocation: Property<Boolean> = objectFactory.property(true)

/**
* Prefix used for auto relocation of packages in the dependencies.
*
Expand Down Expand Up @@ -431,6 +440,7 @@ public abstract class ShadowJar : Jar() {
transformers = transformers.get(),
relocators = relocators.get() + packageRelocators,
unusedClasses = unusedClasses,
enableKotlinModuleRelocation = enableKotlinModuleRelocation.get(),
preserveFileTimestamps = isPreserveFileTimestamps,
failOnDuplicateEntries = failOnDuplicateEntries.get(),
metadataCharset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class ShadowPropertiesTest {
with(shadowJarTask) {
assertThat(addMultiReleaseAttribute.get()).isTrue()
assertThat(enableAutoRelocation.get()).isFalse()
assertThat(enableKotlinModuleRelocation.get()).isTrue()
assertThat(failOnDuplicateEntries.get()).isFalse()
assertThat(minimizeJar.get()).isFalse()
assertThat(mainClass.orNull).isNull()
Expand Down