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..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 @@ -10,6 +12,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 +271,61 @@ 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' + } + relocate('kotlin.', 'shadow.kotlin.') { + exclude('kotlin/kotlin.kotlin_builtins') + } + relocate('org.', 'shadow.org.') + 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]", + ) + 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 { return if (exclude) { // Disable the stdlib dependency added via `implementation`.