From 7ab3258ee1f8802d795c15b919dd1151a19c1218 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 16 Apr 2025 09:17:42 +0800 Subject: [PATCH 01/17] Add `isSkipStringLiteral` for `Relocator` --- api/shadow.api | 5 ++++- .../jengelman/gradle/plugins/shadow/relocation/Relocator.kt | 4 ++++ .../gradle/plugins/shadow/relocation/SimpleRelocator.kt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/api/shadow.api b/api/shadow.api index 741150c7b..478ab011f 100644 --- a/api/shadow.api +++ b/api/shadow.api @@ -118,6 +118,7 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/reloc public abstract fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String; public abstract fun canRelocateClass (Ljava/lang/String;)Z public abstract fun canRelocatePath (Ljava/lang/String;)Z + public abstract fun isSkipStringLiteral ()Z public abstract fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String; public abstract fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String; } @@ -133,7 +134,8 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Z)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZZ)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String; public fun canRelocateClass (Ljava/lang/String;)Z public fun canRelocatePath (Ljava/lang/String;)Z @@ -143,6 +145,7 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat public final fun getIncludes ()Ljava/util/Set; public fun hashCode ()I public fun include (Ljava/lang/String;)V + public fun isSkipStringLiteral ()Z public fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String; public fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String; } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt index 073c29726..ae3ac14a0 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt @@ -1,6 +1,7 @@ package com.github.jengelman.gradle.plugins.shadow.relocation import com.github.jengelman.gradle.plugins.shadow.transformers.CacheableTransformer +import org.gradle.api.tasks.Internal /** * Modified from [org.apache.maven.plugins.shade.relocation.Relocator.java](https://github.com/apache/maven-shade-plugin/blob/master/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java). @@ -19,6 +20,9 @@ public interface Relocator { public fun applyToSourceContent(sourceContent: String): String + @get:Internal + public val isSkipStringLiteral: Boolean + public companion object { public val ROLE: String = Relocator::class.java.name } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt index c5ee0e436..168dee64d 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt @@ -19,6 +19,7 @@ public open class SimpleRelocator @JvmOverloads constructor( includes: List? = null, excludes: List? = null, private val rawString: Boolean = false, + override val isSkipStringLiteral: Boolean = true, ) : Relocator { private val pattern: String private val pathPattern: String From d15966888b9b7b5c5181bdda1266d8f028894471 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 16 Apr 2025 15:09:04 +0800 Subject: [PATCH 02/17] Check `mapLiterals` in `RelocatorRemapper` --- .../plugins/shadow/internal/RelocatorRemapper.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index 42c0e69d1..5701e6b08 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -19,13 +19,17 @@ internal class RelocatorRemapper( override fun mapValue(value: Any): Any { return if (value is String) { - map(value) + mapName(value, mapLiterals = true) } else { super.mapValue(value) } } - override fun map(name: String): String { + override fun map(internalName: String): String = mapName(internalName) + + fun mapPath(path: String): String = map(path.substring(0, path.indexOf('.'))) + + private fun mapName(name: String, mapLiterals: Boolean = false): String { var newName = name var prefix = "" var suffix = "" @@ -38,7 +42,9 @@ internal class RelocatorRemapper( } for (relocator in relocators) { - if (relocator.canRelocateClass(newName)) { + if (mapLiterals && relocator.isSkipStringLiteral) { + return name + } else if (relocator.canRelocateClass(newName)) { return prefix + relocator.relocateClass(newName) + suffix } else if (relocator.canRelocatePath(newName)) { return prefix + relocator.relocatePath(newName) + suffix @@ -47,8 +53,4 @@ internal class RelocatorRemapper( return name } - - fun mapPath(path: String): String { - return map(path.substring(0, path.indexOf('.'))) - } } From efccd57709e0c8398713a3c8f89c990b118816a4 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 16 Apr 2025 15:15:35 +0800 Subject: [PATCH 03/17] Make isSkipStringLiteral configurable --- api/shadow.api | 1 + .../gradle/plugins/shadow/relocation/SimpleRelocator.kt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/api/shadow.api b/api/shadow.api index 478ab011f..cca7414c8 100644 --- a/api/shadow.api +++ b/api/shadow.api @@ -148,6 +148,7 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat public fun isSkipStringLiteral ()Z public fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String; public fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String; + public fun setSkipStringLiteral (Z)V } public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter : java/io/Serializable { diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt index 168dee64d..e28681735 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt @@ -19,7 +19,7 @@ public open class SimpleRelocator @JvmOverloads constructor( includes: List? = null, excludes: List? = null, private val rawString: Boolean = false, - override val isSkipStringLiteral: Boolean = true, + @Input override var isSkipStringLiteral: Boolean = true, ) : Relocator { private val pattern: String private val pathPattern: String @@ -138,6 +138,7 @@ public open class SimpleRelocator @JvmOverloads constructor( if (this === other) return true if (other !is SimpleRelocator) return false return rawString == other.rawString && + isSkipStringLiteral == other.isSkipStringLiteral && pattern == other.pattern && pathPattern == other.pathPattern && shadedPattern == other.shadedPattern && @@ -150,6 +151,7 @@ public open class SimpleRelocator @JvmOverloads constructor( override fun hashCode(): Int { var result = rawString.hashCode() + result = 31 * result + isSkipStringLiteral.hashCode() result = 31 * result + pattern.hashCode() result = 31 * result + pathPattern.hashCode() result = 31 * result + shadedPattern.hashCode() From 233e9e04f03b69aff72adc5b30d245605ae6bb15 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 16 Apr 2025 15:54:13 +0800 Subject: [PATCH 04/17] Test `canDisableRelocateStringConstants` --- .../gradle/plugins/shadow/RelocationTest.kt | 47 +++++++++++++++++++ .../shadow/internal/RelocatorRemapper.kt | 2 +- .../plugins/shadow/relocation/Relocator.kt | 2 +- .../shadow/relocation/SimpleRelocator.kt | 6 +-- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt index eb1543a82..bc8d7694e 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt @@ -8,9 +8,11 @@ import assertk.assertions.isInstanceOf import assertk.assertions.isNotEmpty import assertk.fail import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.Companion.SHADOW_JAR_TASK_NAME +import com.github.jengelman.gradle.plugins.shadow.internal.mainClassAttributeKey import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowCopyAction.Companion.CONSTANT_TIME_FOR_ZIP_ENTRIES import com.github.jengelman.gradle.plugins.shadow.util.Issue import com.github.jengelman.gradle.plugins.shadow.util.containsOnly +import com.github.jengelman.gradle.plugins.shadow.util.runProcess import java.net.URLClassLoader import kotlin.io.path.appendText import kotlin.io.path.writeText @@ -581,6 +583,51 @@ class RelocationTest : BasePluginTest() { } } + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun canDisableRelocateStringConstants(skipStringLiteral: Boolean) { + writeClass { + """ + package my; + public class Main { + public static final String junit = "junit.framework.Test"; + public static void main(String[] args) { + System.out.println(getValue() + junit); + } + // Use this method to force the compiler to not inline the string literal. + private static String getValue() { return "the value is "; } + } + """.trimIndent() + } + projectScriptPath.appendText( + """ + $shadowJar { + manifest { + attributes '$mainClassAttributeKey': 'my.Main' + } + relocate('junit', 'foo.junit') { + skipStringLiteral = $skipStringLiteral + } + } + """.trimIndent(), + ) + + run(shadowJarTask) { + it.withDebug(true) + } + + val pathString = outputShadowJar.use { it.toString() } + val result = runProcess("java", "-jar", pathString) + + assertThat(result).contains( + if (skipStringLiteral) { + "the value is junit.framework.Test" + } else { + "the value is foo.junit.framework.Test" + }, + ) + } + private companion object { @JvmStatic fun prefixProvider() = listOf( diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index 5701e6b08..c29264209 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -42,7 +42,7 @@ internal class RelocatorRemapper( } for (relocator in relocators) { - if (mapLiterals && relocator.isSkipStringLiteral) { + if (mapLiterals && relocator.skipStringLiteral) { return name } else if (relocator.canRelocateClass(newName)) { return prefix + relocator.relocateClass(newName) + suffix diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt index ae3ac14a0..5768f68c6 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt @@ -21,7 +21,7 @@ public interface Relocator { public fun applyToSourceContent(sourceContent: String): String @get:Internal - public val isSkipStringLiteral: Boolean + public val skipStringLiteral: Boolean public companion object { public val ROLE: String = Relocator::class.java.name diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt index e28681735..360387eec 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt @@ -19,7 +19,7 @@ public open class SimpleRelocator @JvmOverloads constructor( includes: List? = null, excludes: List? = null, private val rawString: Boolean = false, - @Input override var isSkipStringLiteral: Boolean = true, + @get:Input override var skipStringLiteral: Boolean = false, ) : Relocator { private val pattern: String private val pathPattern: String @@ -138,7 +138,7 @@ public open class SimpleRelocator @JvmOverloads constructor( if (this === other) return true if (other !is SimpleRelocator) return false return rawString == other.rawString && - isSkipStringLiteral == other.isSkipStringLiteral && + skipStringLiteral == other.skipStringLiteral && pattern == other.pattern && pathPattern == other.pathPattern && shadedPattern == other.shadedPattern && @@ -151,7 +151,7 @@ public open class SimpleRelocator @JvmOverloads constructor( override fun hashCode(): Int { var result = rawString.hashCode() - result = 31 * result + isSkipStringLiteral.hashCode() + result = 31 * result + skipStringLiteral.hashCode() result = 31 * result + pattern.hashCode() result = 31 * result + pathPattern.hashCode() result = 31 * result + shadedPattern.hashCode() From de55c7b025f90b0b4a32a935846903ff8cd96232 Mon Sep 17 00:00:00 2001 From: Goooler Date: Thu, 17 Apr 2025 18:17:16 +0800 Subject: [PATCH 05/17] Fix `canDisableRelocateStringConstants` --- .../gradle/plugins/shadow/RelocationTest.kt | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt index 99a9ac84e..e93e2fca3 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt @@ -585,16 +585,7 @@ class RelocationTest : BasePluginTest() { @Test fun relocateStringConstantsByDefault() { - writeClass { - """ - package my; - public class Main { - public static void main(String[] args) { - System.out.println("junit.framework.Test"); - } - } - """.trimIndent() - } + writeClassWithStringRef() projectScriptPath.appendText( """ $shadowJar { @@ -614,22 +605,13 @@ class RelocationTest : BasePluginTest() { ) } + @Issue( + "https://github.com/GradleUp/shadow/issues/232", + ) @ParameterizedTest @ValueSource(booleans = [false, true]) fun canDisableRelocateStringConstants(skipStringLiteral: Boolean) { - writeClass { - """ - package my; - public class Main { - public static final String junit = "junit.framework.Test"; - public static void main(String[] args) { - System.out.println(getValue() + junit); - } - // Use this method to force the compiler to not inline the string literal. - private static String getValue() { return "the value is "; } - } - """.trimIndent() - } + writeClassWithStringRef() projectScriptPath.appendText( """ $shadowJar { @@ -643,22 +625,31 @@ class RelocationTest : BasePluginTest() { """.trimIndent(), ) - run(shadowJarTask) { - it.withDebug(true) - } - - val pathString = outputShadowJar.use { it.toString() } - val result = runProcess("java", "-jar", pathString) + run(shadowJarTask) + val result = runProcess("java", "-jar", outputShadowJar.use { it.toString() }) assertThat(result).contains( if (skipStringLiteral) { - "the value is junit.framework.Test" + "junit.framework.Test" } else { - "the value is foo.junit.framework.Test" + "foo.junit.framework.Test" }, ) } + private fun writeClassWithStringRef() { + writeClass { + """ + package my; + public class Main { + public static void main(String[] args) { + System.out.println("junit.framework.Test"); + } + } + """.trimIndent() + } + } + private companion object { @JvmStatic fun prefixProvider() = listOf( From 3388470ca72201040f134f32df4b5b3baf0a7c5c Mon Sep 17 00:00:00 2001 From: Goooler Date: Thu, 17 Apr 2025 18:23:19 +0800 Subject: [PATCH 06/17] Dump API --- api/shadow.api | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/shadow.api b/api/shadow.api index cca7414c8..e3f1f0adf 100644 --- a/api/shadow.api +++ b/api/shadow.api @@ -118,7 +118,7 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/reloc public abstract fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String; public abstract fun canRelocateClass (Ljava/lang/String;)Z public abstract fun canRelocatePath (Ljava/lang/String;)Z - public abstract fun isSkipStringLiteral ()Z + public abstract fun getSkipStringLiteral ()Z public abstract fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String; public abstract fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String; } @@ -143,9 +143,9 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat public fun exclude (Ljava/lang/String;)V public final fun getExcludes ()Ljava/util/Set; public final fun getIncludes ()Ljava/util/Set; + public fun getSkipStringLiteral ()Z public fun hashCode ()I public fun include (Ljava/lang/String;)V - public fun isSkipStringLiteral ()Z public fun relocateClass-XBGRxQs (Ljava/lang/String;)Ljava/lang/String; public fun relocatePath-bvWaKNU (Ljava/lang/String;)Ljava/lang/String; public fun setSkipStringLiteral (Z)V From 4dc3d9b851d6a17ce886664bf78b7426ee0bd18b Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Apr 2025 17:36:55 +0800 Subject: [PATCH 07/17] Update changelog --- docs/changes/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changes/README.md b/docs/changes/README.md index eef391d35..9d2ddff95 100644 --- a/docs/changes/README.md +++ b/docs/changes/README.md @@ -2,6 +2,10 @@ ## [Unreleased](https://github.com/GradleUp/shadow/compare/9.0.0-beta12...HEAD) - 2025-xx-xx +**Added** + +- Support disabling of string constant remapping. ([#1401](https://github.com/GradleUp/shadow/pull/1401)) + **Changed** - Set `Main-Class` attr for KMP 1.9.0 or above. ([#1410](https://github.com/GradleUp/shadow/pull/1410)) From 0d462ac86d9f5c2578e1ce292000a490a31cfa9b Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 30 Apr 2025 15:38:31 +0800 Subject: [PATCH 08/17] Update changelog --- docs/changes/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/changes/README.md b/docs/changes/README.md index 3f7056f49..0b42764d9 100644 --- a/docs/changes/README.md +++ b/docs/changes/README.md @@ -2,13 +2,12 @@ ## [Unreleased](https://github.com/GradleUp/shadow/compare/9.0.0-beta13...HEAD) - 2025-xx-xx - -## [9.0.0-beta13](https://github.com/GradleUp/shadow/releases/tag/9.0.0-beta13) - 2025-04-29 - **Added** - Support disabling of string constant remapping. ([#1401](https://github.com/GradleUp/shadow/pull/1401)) +## [9.0.0-beta13](https://github.com/GradleUp/shadow/releases/tag/9.0.0-beta13) - 2025-04-29 + **Changed** - Set `Main-Class` attr for KMP 1.9.0 or above. ([#1410](https://github.com/GradleUp/shadow/pull/1410)) From 79e62473966380882c5efa602e65e508517f6a2c Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Mon, 14 Jul 2025 16:14:06 +0800 Subject: [PATCH 09/17] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../gradle/plugins/shadow/internal/RelocatorRemapper.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index c29264209..d3107d49d 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -27,7 +27,14 @@ internal class RelocatorRemapper( override fun map(internalName: String): String = mapName(internalName) - fun mapPath(path: String): String = map(path.substring(0, path.indexOf('.'))) + fun mapPath(path: String): String { + val dotIndex = path.indexOf('.') + return if (dotIndex == -1) { + path // Return the original path if no period is found + } else { + map(path.substring(0, dotIndex)) + } + } private fun mapName(name: String, mapLiterals: Boolean = false): String { var newName = name From 78e9fbadd790af6cdb450c714cb5190f4bf59f8b Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 15:21:04 +0800 Subject: [PATCH 10/17] Cleanups --- .../gradle/plugins/shadow/internal/RelocatorRemapper.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index d3107d49d..eae7b68e6 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -29,11 +29,7 @@ internal class RelocatorRemapper( fun mapPath(path: String): String { val dotIndex = path.indexOf('.') - return if (dotIndex == -1) { - path // Return the original path if no period is found - } else { - map(path.substring(0, dotIndex)) - } + return if (dotIndex == -1) path else map(path.take(dotIndex)) } private fun mapName(name: String, mapLiterals: Boolean = false): String { From 5530f3ee36824abf68aacd6fad04a3a3502f582a Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 15:27:52 +0800 Subject: [PATCH 11/17] Mark `skipStringLiteral` as `Input` --- api/shadow.api | 2 +- .../jengelman/gradle/plugins/shadow/relocation/Relocator.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/shadow.api b/api/shadow.api index 63827a174..a5c8640d3 100644 --- a/api/shadow.api +++ b/api/shadow.api @@ -112,7 +112,7 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/reloc public abstract fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String; public abstract fun canRelocateClass (Ljava/lang/String;)Z public abstract fun canRelocatePath (Ljava/lang/String;)Z - public abstract fun getSkipStringLiteral ()Z + public fun getSkipStringLiteral ()Z public abstract fun relocateClass (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocateClassContext;)Ljava/lang/String; public abstract fun relocatePath (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocatePathContext;)Ljava/lang/String; } diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt index 5768f68c6..c8c84e98c 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt @@ -1,7 +1,7 @@ package com.github.jengelman.gradle.plugins.shadow.relocation import com.github.jengelman.gradle.plugins.shadow.transformers.CacheableTransformer -import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.Input /** * Modified from [org.apache.maven.plugins.shade.relocation.Relocator.java](https://github.com/apache/maven-shade-plugin/blob/master/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java). @@ -20,8 +20,8 @@ public interface Relocator { public fun applyToSourceContent(sourceContent: String): String - @get:Internal - public val skipStringLiteral: Boolean + @get:Input + public val skipStringLiteral: Boolean get() = false public companion object { public val ROLE: String = Relocator::class.java.name From 87a5b3d24af834ce8a6f61458671c0e3942f58d5 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 15:34:21 +0800 Subject: [PATCH 12/17] Rename `skipStringLiteral` to `skipStringConstants` --- api/shadow.api | 6 +++--- .../gradle/plugins/shadow/RelocationTest.kt | 13 ++++--------- .../plugins/shadow/internal/RelocatorRemapper.kt | 2 +- .../gradle/plugins/shadow/relocation/Relocator.kt | 7 ++++++- .../plugins/shadow/relocation/SimpleRelocator.kt | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/api/shadow.api b/api/shadow.api index a5c8640d3..a82d5997b 100644 --- a/api/shadow.api +++ b/api/shadow.api @@ -112,7 +112,7 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/reloc public abstract fun applyToSourceContent (Ljava/lang/String;)Ljava/lang/String; public abstract fun canRelocateClass (Ljava/lang/String;)Z public abstract fun canRelocatePath (Ljava/lang/String;)Z - public fun getSkipStringLiteral ()Z + public fun getSkipStringConstants ()Z public abstract fun relocateClass (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocateClassContext;)Ljava/lang/String; public abstract fun relocatePath (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocatePathContext;)Ljava/lang/String; } @@ -137,12 +137,12 @@ public class com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocat public fun exclude (Ljava/lang/String;)V public final fun getExcludes ()Ljava/util/Set; public final fun getIncludes ()Ljava/util/Set; - public fun getSkipStringLiteral ()Z + public fun getSkipStringConstants ()Z public fun hashCode ()I public fun include (Ljava/lang/String;)V public fun relocateClass (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocateClassContext;)Ljava/lang/String; public fun relocatePath (Lcom/github/jengelman/gradle/plugins/shadow/relocation/RelocatePathContext;)Ljava/lang/String; - public fun setSkipStringLiteral (Z)V + public fun setSkipStringConstants (Z)V } public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks/DependencyFilter : java/io/Serializable { diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt index e93e2fca3..d8c42802c 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt @@ -610,7 +610,7 @@ class RelocationTest : BasePluginTest() { ) @ParameterizedTest @ValueSource(booleans = [false, true]) - fun canDisableRelocateStringConstants(skipStringLiteral: Boolean) { + fun canDisableRelocateStringConstants(skipStringConstants: Boolean) { writeClassWithStringRef() projectScriptPath.appendText( """ @@ -619,7 +619,7 @@ class RelocationTest : BasePluginTest() { attributes '$mainClassAttributeKey': 'my.Main' } relocate('junit', 'foo.junit') { - skipStringLiteral = $skipStringLiteral + skipStringConstants = $skipStringConstants } } """.trimIndent(), @@ -628,13 +628,8 @@ class RelocationTest : BasePluginTest() { run(shadowJarTask) val result = runProcess("java", "-jar", outputShadowJar.use { it.toString() }) - assertThat(result).contains( - if (skipStringLiteral) { - "junit.framework.Test" - } else { - "foo.junit.framework.Test" - }, - ) + val expected = if (skipStringConstants) "junit.framework.Test" else "foo.junit.framework.Test" + assertThat(result).contains(expected) } private fun writeClassWithStringRef() { diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index eae7b68e6..232f5eccd 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -45,7 +45,7 @@ internal class RelocatorRemapper( } for (relocator in relocators) { - if (mapLiterals && relocator.skipStringLiteral) { + if (mapLiterals && relocator.skipStringConstants) { return name } else if (relocator.canRelocateClass(newName)) { return prefix + relocator.relocateClass(newName) + suffix diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt index c8c84e98c..50616f83e 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/Relocator.kt @@ -20,8 +20,13 @@ public interface Relocator { public fun applyToSourceContent(sourceContent: String): String + /** + * Indicates whether this relocator should skip relocating string constants. + * + * Defaults to `false`. + */ @get:Input - public val skipStringLiteral: Boolean get() = false + public val skipStringConstants: Boolean get() = false public companion object { public val ROLE: String = Relocator::class.java.name diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt index 55117aef3..1ae34df27 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt @@ -19,7 +19,7 @@ public open class SimpleRelocator @JvmOverloads constructor( includes: List? = null, excludes: List? = null, private val rawString: Boolean = false, - @get:Input override var skipStringLiteral: Boolean = false, + @get:Input override var skipStringConstants: Boolean = false, ) : Relocator { private val pattern: String private val pathPattern: String @@ -138,7 +138,7 @@ public open class SimpleRelocator @JvmOverloads constructor( if (this === other) return true if (other !is SimpleRelocator) return false return rawString == other.rawString && - skipStringLiteral == other.skipStringLiteral && + skipStringConstants == other.skipStringConstants && pattern == other.pattern && pathPattern == other.pathPattern && shadedPattern == other.shadedPattern && @@ -151,7 +151,7 @@ public open class SimpleRelocator @JvmOverloads constructor( override fun hashCode(): Int { var result = rawString.hashCode() - result = 31 * result + skipStringLiteral.hashCode() + result = 31 * result + skipStringConstants.hashCode() result = 31 * result + pattern.hashCode() result = 31 * result + pathPattern.hashCode() result = 31 * result + shadedPattern.hashCode() From 795378348f34b0b7b967d58b51dc2d2befce7654 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 15:40:32 +0800 Subject: [PATCH 13/17] Update doc --- docs/configuration/relocation/README.md | 57 +++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/configuration/relocation/README.md b/docs/configuration/relocation/README.md index 3cfe0e8d0..90801643f 100644 --- a/docs/configuration/relocation/README.md +++ b/docs/configuration/relocation/README.md @@ -93,6 +93,63 @@ expression in `%regex[]` before passing it to `include`/`exclude`. } ``` +## Skipping Relocation for String Constants + +If there is a class like: + +```java +package foo; + +public class Bar { + public static void main(String[] args) { + System.out.println("foo.Bar"); + } +} +``` + +in your project, and you configure the relocation like: + +=== "Kotlin" + + ```kotlin + tasks.shadowJar { + relocate("foo", "my.foo") + } + ``` + +=== "Groovy" + + ```groovy + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { + relocate 'foo', 'my.foo' + } + ``` + +the string constant `"foo.Bar"` will be relocated to `"my.foo.Bar"` by default. This may not be want you want, you can +skip relocating string constants in the classes like: + +=== "Kotlin" + + ```kotlin + tasks.shadowJar { + relocate("foo", "my.foo") { + // Optionally, defaults to `false`. + skipStringConstants = true + } + } + ``` + +=== "Groovy" + + ```groovy + tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) { + relocate('foo', 'my.foo') { + // Optionally, defaults to `false`. + skipStringConstants = true + } + } + ``` + ## Automatically Relocating Dependencies Shadow is shipped with a task that can be used to automatically configure all packages from all dependencies to be From d5060b1fbf5cd0ed378122ae446c4e3eedc1a0ff Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Wed, 23 Jul 2025 15:52:56 +0800 Subject: [PATCH 14/17] Update src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../gradle/plugins/shadow/internal/RelocatorRemapper.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index 232f5eccd..320129d7b 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -28,8 +28,7 @@ internal class RelocatorRemapper( override fun map(internalName: String): String = mapName(internalName) fun mapPath(path: String): String { - val dotIndex = path.indexOf('.') - return if (dotIndex == -1) path else map(path.take(dotIndex)) + return path.substringBefore('.') } private fun mapName(name: String, mapLiterals: Boolean = false): String { From 95ea038601220a03e04e9974453805f11e7779b6 Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Wed, 23 Jul 2025 15:53:04 +0800 Subject: [PATCH 15/17] Update docs/configuration/relocation/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/configuration/relocation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/relocation/README.md b/docs/configuration/relocation/README.md index 90801643f..c8fc680dd 100644 --- a/docs/configuration/relocation/README.md +++ b/docs/configuration/relocation/README.md @@ -125,7 +125,7 @@ in your project, and you configure the relocation like: } ``` -the string constant `"foo.Bar"` will be relocated to `"my.foo.Bar"` by default. This may not be want you want, you can +the string constant `"foo.Bar"` will be relocated to `"my.foo.Bar"` by default. This may not be what you want, you can skip relocating string constants in the classes like: === "Kotlin" From 1b09b15d1a6caddb0aeb2f391d29303214be3c00 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 16:11:16 +0800 Subject: [PATCH 16/17] Revert "Update src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt" This reverts commit d5060b1fbf5cd0ed378122ae446c4e3eedc1a0ff. --- .../gradle/plugins/shadow/internal/RelocatorRemapper.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt index 320129d7b..232f5eccd 100644 --- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt +++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt @@ -28,7 +28,8 @@ internal class RelocatorRemapper( override fun map(internalName: String): String = mapName(internalName) fun mapPath(path: String): String { - return path.substringBefore('.') + val dotIndex = path.indexOf('.') + return if (dotIndex == -1) path else map(path.take(dotIndex)) } private fun mapName(name: String, mapLiterals: Boolean = false): String { From 72368adfb0a6b42a61b68b5c7a4ffddd15fec763 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 23 Jul 2025 16:19:25 +0800 Subject: [PATCH 17/17] Update changelog --- docs/changes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes/README.md b/docs/changes/README.md index 135b6039f..7bd6cf4cd 100644 --- a/docs/changes/README.md +++ b/docs/changes/README.md @@ -4,7 +4,7 @@ **Added** -- Support disabling of string constant remapping. ([#1401](https://github.com/GradleUp/shadow/pull/1401)) +- Support skipping string constant remapping. ([#1401](https://github.com/GradleUp/shadow/pull/1401)) - Let `assemble` depend on `shadowJar`. ([#1524](https://github.com/GradleUp/shadow/pull/1524)) - Fail build when inputting AAR files or using Shadow with AGP. ([#1530](https://github.com/GradleUp/shadow/pull/1530))