From 4424438fb501dd1ca2c25a5493c86193f4cb14db Mon Sep 17 00:00:00 2001 From: Goooler Date: Thu, 4 Sep 2025 14:58:22 +0800 Subject: [PATCH 1/4] Test `relocateKotlinReflectFull` ``` Error occurred when running command line: Exception in thread "main" java.lang.AssertionError: Built-in class shadow.kotlin.Any is not found at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:93) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:88) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:681) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getBuiltInClassByName(KotlinBuiltIns.java:223) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAny(KotlinBuiltIns.java:228) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAnyType(KotlinBuiltIns.java:504) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses$MockClassDescriptor.(NotFoundClasses.kt:62) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses.classes$lambda$2(NotFoundClasses.kt:45) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses.accessor$NotFoundClasses$lambda1(NotFoundClasses.kt) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses$$Lambda$1.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:681) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses.getClass(NotFoundClasses.kt:97) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.TypeDeserializer.typeConstructor$notFoundClass(TypeDeserializer.kt:151) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.TypeDeserializer.typeConstructor(TypeDeserializer.kt:156) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.TypeDeserializer.simpleType(TypeDeserializer.kt:91) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.TypeDeserializer.type(TypeDeserializer.kt:68) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassTypeConstructor.computeSupertypes(DeserializedClassDescriptor.kt:242) at shadow.kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.supertypes$lambda$0(AbstractTypeConstructor.kt:78) at shadow.kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.accessor$AbstractTypeConstructor$lambda0(AbstractTypeConstructor.kt) at shadow.kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor$$Lambda$0.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:481) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValueWithPostCompute.invoke(LockBasedStorageManager.java:512) at shadow.kotlin.reflect.jvm.internal.impl.types.AbstractTypeConstructor.getSupertypes(AbstractTypeConstructor.kt:27) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getNonDeclaredVariableNames(DeserializedClassDescriptor.kt:360) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.variableNames_delegate$lambda$9(DeserializedMemberScope.kt:262) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.accessor$DeserializedMemberScope$OptimizedImplementation$lambda4(DeserializedMemberScope.kt) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation$$Lambda$4.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527) at shadow.kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:42) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.getVariableNames(DeserializedMemberScope.kt:261) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope$OptimizedImplementation.addFunctionsAndPropertiesTo(DeserializedMemberScope.kt:349) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedMemberScope.computeDescriptors(DeserializedMemberScope.kt:115) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.allDescriptors$lambda$2(DeserializedClassDescriptor.kt:279) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.accessor$DeserializedClassDescriptor$DeserializedClassMemberScope$lambda1(DeserializedClassDescriptor.kt) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope$$Lambda$1.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527) at shadow.kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedClassDescriptor$DeserializedClassMemberScope.getContributedDescriptors(DeserializedClassDescriptor.kt:289) at shadow.kotlin.reflect.jvm.internal.impl.resolve.scopes.ResolutionScope$DefaultImpls.getContributedDescriptors$default(ResolutionScope.kt:50) at shadow.kotlin.reflect.jvm.internal.KDeclarationContainerImpl.getMembers(KDeclarationContainerImpl.kt:58) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.declaredNonStaticMembers_delegate$lambda$24(KClassImpl.kt:206) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.accessor$KClassImpl$Data$lambda11(KClassImpl.kt) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data$$Lambda$11.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) at shadow.kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt:206) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.allNonStaticMembers_delegate$lambda$28(KClassImpl.kt:215) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.accessor$KClassImpl$Data$lambda15(KClassImpl.kt) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data$$Lambda$15.invoke(Unknown Source) at shadow.kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:70) at shadow.kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) at shadow.kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt:215) at shadow.kotlin.reflect.full.KClasses.getMemberProperties(KClasses.kt:146) at my.MainKt.main(Main.kt:5) at my.MainKt.main(Main.kt) ``` --- .../plugins/shadow/KotlinPluginsTest.kt | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt index 1122e76de..c56807654 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt @@ -10,6 +10,7 @@ import com.github.jengelman.gradle.plugins.shadow.testkit.containsOnly import com.github.jengelman.gradle.plugins.shadow.testkit.getMainAttr import com.github.jengelman.gradle.plugins.shadow.util.Issue import com.github.jengelman.gradle.plugins.shadow.util.JvmLang +import com.github.jengelman.gradle.plugins.shadow.util.runProcess import kotlin.io.path.appendText import kotlin.io.path.writeText import org.junit.jupiter.api.BeforeEach @@ -268,6 +269,49 @@ class KotlinPluginsTest : BasePluginTest() { ) } + @Issue( + "https://github.com/GradleUp/shadow/issues/1622", + ) + @Test + fun relocateKotlinReflectFull() { + projectScript.writeText( + """ + ${getDefaultProjectBuildScript(plugin = "org.jetbrains.kotlin.jvm", withGroup = true, withVersion = true)} + dependencies { + implementation 'org.jetbrains.kotlin:kotlin-reflect' + } + $shadowJarTask { + manifest { + attributes '$mainClassAttributeKey': 'my.MainKt' + } + enableAutoRelocation = true + mergeServiceFiles() // Merge and relocate service files from kotlin-reflect. + } + """.trimIndent(), + ) + writeClass(jvmLang = JvmLang.Kotlin) { + """ + package my + import kotlin.reflect.full.memberProperties + + fun main() { + println(MemberClass()::class.memberProperties) + } + private class MemberClass { + val prop1 = "property 1" + val prop2 by lazy { "property 2" } + } + """.trimIndent() + } + + run(shadowJarPath) + val result = runProcess("java", "-jar", outputShadowedJar.use { it.toString() }) + + assertThat(result).contains( + "[val my.MemberClass.prop1: kotlin.String, val my.MemberClass.prop2: kotlin.String]", + ) + } + private fun compileOnlyStdlib(exclude: Boolean): String { return if (exclude) { // Disable the stdlib dependency added via `implementation`. From 2ce9116778d23fd69ded256bf6e4f5ee335e4e45 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 17 Sep 2025 16:36:02 +0800 Subject: [PATCH 2/4] Relocate `kotlin.` to `shadow.kotlin.` ``` Error occurred when running command line: Exception in thread "main" java.lang.AssertionError: Built-in class kotlin.Any is not found at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:93) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:88) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578) at shadow.kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:681) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getBuiltInClassByName(KotlinBuiltIns.java:223) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAny(KotlinBuiltIns.java:228) at shadow.kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns.getAnyType(KotlinBuiltIns.java:504) at shadow.kotlin.reflect.jvm.internal.impl.descriptors.NotFoundClasses$MockClassDescriptor.(NotFoundClasses.kt:62) ``` --- .../github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt index c56807654..1b934d08d 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt @@ -284,7 +284,7 @@ class KotlinPluginsTest : BasePluginTest() { manifest { attributes '$mainClassAttributeKey': 'my.MainKt' } - enableAutoRelocation = true + relocate('kotlin.', 'shadow.kotlin.') mergeServiceFiles() // Merge and relocate service files from kotlin-reflect. } """.trimIndent(), From 5865b62eb0b8e3b57ada4b92ab8f2b1489964a7f Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 17 Sep 2025 16:37:43 +0800 Subject: [PATCH 3/4] Exclude `kotlin/kotlin.kotlin_builtins` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` OLD: old.jar NEW: new.jar JAR │ old │ new │ diff ───────┼──────────┼──────────┼────── class │ 12.6 MiB │ 12.6 MiB │ 0 B other │ 74.6 KiB │ 74.6 KiB │ 0 B ───────┼──────────┼──────────┼────── total │ 12.7 MiB │ 12.7 MiB │ 0 B CLASSES │ old │ new │ diff ─────────┼───────┼───────┼─────────── classes │ 3149 │ 3149 │ 0 (+0 -0) methods │ 27835 │ 27835 │ 0 (+0 -0) fields │ 6257 │ 6257 │ 0 (+0 -0) ================= ==== JAR ==== ================= size │ diff │ path ──────────┼───────────┼──────────────────────────────────────── │ -28.7 KiB │ - shadow/kotlin/kotlin.kotlin_builtins 28.7 KiB │ +28.7 KiB │ + kotlin/kotlin.kotlin_builtins 0 B │ 0 B │ + kotlin/ ──────────┼───────────┼──────────────────────────────────────── 28.7 KiB │ 0 B │ (total) ``` --- .../jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt index 1b934d08d..2b8e18686 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt @@ -284,7 +284,9 @@ class KotlinPluginsTest : BasePluginTest() { manifest { attributes '$mainClassAttributeKey': 'my.MainKt' } - relocate('kotlin.', 'shadow.kotlin.') + relocate('kotlin.', 'shadow.kotlin.') { + exclude('kotlin/kotlin.kotlin_builtins') + } mergeServiceFiles() // Merge and relocate service files from kotlin-reflect. } """.trimIndent(), From c39f2c81c352c4182e427875515b89c1655bcc45 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 17 Sep 2025 16:45:54 +0800 Subject: [PATCH 4/4] Relocate `org.` to `shadow.org.` --- .../gradle/plugins/shadow/KotlinPluginsTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt index 2b8e18686..7d9636a9b 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/KotlinPluginsTest.kt @@ -1,8 +1,10 @@ package com.github.jengelman.gradle.plugins.shadow +import assertk.all import assertk.assertThat import assertk.assertions.contains import assertk.assertions.isEqualTo +import assertk.assertions.isTrue import com.github.jengelman.gradle.plugins.shadow.internal.mainClassAttributeKey import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.Companion.SHADOW_JAR_TASK_NAME import com.github.jengelman.gradle.plugins.shadow.testkit.containsAtLeast @@ -287,6 +289,7 @@ class KotlinPluginsTest : BasePluginTest() { relocate('kotlin.', 'shadow.kotlin.') { exclude('kotlin/kotlin.kotlin_builtins') } + relocate('org.', 'shadow.org.') mergeServiceFiles() // Merge and relocate service files from kotlin-reflect. } """.trimIndent(), @@ -312,6 +315,15 @@ class KotlinPluginsTest : BasePluginTest() { assertThat(result).contains( "[val my.MemberClass.prop1: kotlin.String, val my.MemberClass.prop2: kotlin.String]", ) + assertThat(outputShadowedJar).useAll { + // All dependency classes are relocated. + transform { actual -> + actual.entries().toList() + .map { it.name.removePrefix("META-INF/versions/9/") } + .filter { it.endsWith(".class") && !it.startsWith("my/") } + .all { it.startsWith("shadow/") } + }.isTrue() + } } private fun compileOnlyStdlib(exclude: Boolean): String {