From c7363adf10160ffb2e298e4e49a3ae51f291a996 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Mon, 31 Oct 2022 22:45:30 +0100 Subject: [PATCH] Align kotlin stdlib jvm variants versions Instead of doing substitution for stdlib, plugin now just aligns jvm variants version in all dependencies to one. This eliminates issue when JPMS module requires kotlin.stdlib.jdk8 (or jdk7) and fails to find it in compilation classpath. Kotlin-stdlib-jdk8(,jdk7) variants in 1.8.0 is empty one, so new approach will not cause duplicate classes in classpath issue. Gradle property to disable alignment was renamed from "kotlin .stdlib.jdk.variants.substitution" to "kotlin.stdlib.jdk.variants .version.alignment" to better reflect new approach. ^KT-54703 Fixed --- .../kotlin/gradle/StdlibAlignmentIT.kt | 89 ++++++++++++++----- .../kotlin/gradle/testbase/assertionsUtils.kt | 2 + .../jpmsProject/application/build.gradle.kts | 13 +++ .../src/main/java/module-info.java | 4 + .../main/java/org/gradle/sample/app/Main.java | 15 ++++ .../org/gradle/sample/app/MessageUtils.java | 7 ++ .../gradle/sample/app/MessageUtilsTest.java | 11 +++ .../testProject/jpmsProject/build.gradle.kts | 6 ++ .../jpmsProject/list/build.gradle.kts | 4 + .../list/src/main/java/module-info.java | 3 + .../org/gradle/sample/list/LinkedList.java | 78 ++++++++++++++++ .../jpmsProject/settings.gradle.kts | 2 + .../jpmsProject/utilities/build.gradle.kts | 7 ++ .../utilities/src/main/java/module-info.java | 4 + .../gradle/sample/utilities/JoinUtils.java | 17 ++++ .../gradle/sample/utilities/SplitUtils.java | 36 ++++++++ .../gradle/sample/utilities/StringUtils.java | 13 +++ .../internal/KotlinDependenciesManagement.kt | 4 +- .../internal/stdlibDependencyManagement.kt | 14 +-- .../gradle/plugin/PropertiesProvider.kt | 8 +- 20 files changed, 301 insertions(+), 36 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/module-info.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/Main.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/MessageUtils.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/test/java/org/gradle/sample/app/MessageUtilsTest.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/module-info.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/org/gradle/sample/list/LinkedList.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/settings.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/module-info.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/JoinUtils.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/SplitUtils.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/StringUtils.java diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/StdlibAlignmentIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/StdlibAlignmentIT.kt index a2669133dee..87a336c3c91 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/StdlibAlignmentIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/StdlibAlignmentIT.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle +import org.gradle.api.JavaVersion import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName @@ -14,9 +15,9 @@ import kotlin.io.path.appendText class StdlibAlignmentIT : KGPBaseTest() { @AndroidGradlePluginTests - @DisplayName("stdlib-jdk7, stdlib-jdk8 are substituted with stdlib:1.8+") + @DisplayName("stdlib-jdk7, stdlib-jdk8 versions aligned with stdlib:1.8+") @GradleAndroidTest - fun testStdlibSubstitutionAndroid( + fun testStdlibAlignmentAndroid( gradleVersion: GradleVersion, agpVersion: String, jdkVersion: JdkVersions.ProvidedJdk @@ -45,9 +46,9 @@ class StdlibAlignmentIT : KGPBaseTest() { } @AndroidGradlePluginTests - @DisplayName("stdlib-jdk7, stdlib-jdk8 substitution with stdlib:1.8+ is possible to disable") + @DisplayName("alignment is possible to disable") @GradleAndroidTest - fun testDisableStdlibSubstitutionAndroid( + fun testDisableStdlibAlignmentAndroid( gradleVersion: GradleVersion, agpVersion: String, jdkVersion: JdkVersions.ProvidedJdk @@ -74,7 +75,7 @@ class StdlibAlignmentIT : KGPBaseTest() { gradleProperties.appendText( """ | - |kotlin.stdlib.jdk.variants.substitution=false + |kotlin.stdlib.jdk.variants.version.alignment=false """.trimMargin() ) @@ -85,9 +86,9 @@ class StdlibAlignmentIT : KGPBaseTest() { } @JvmGradlePluginTests - @DisplayName("substitution is working when stldib-jdk7:1.8+ is added as dependency") + @DisplayName("alignment is working when stdlib-jdk7:1.8+ is added as dependency") @GradleTest - fun stdlibJdk7Substitution(gradleVersion: GradleVersion) { + fun stdlibJdk7Alignment(gradleVersion: GradleVersion) { project("sourceSetsKotlinDsl", gradleVersion) { buildGradleKts.appendText( """ @@ -104,19 +105,17 @@ class StdlibAlignmentIT : KGPBaseTest() { """ |\--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2 | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2 - | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 -> org.jetbrains.kotlin:kotlin-stdlib:${buildOptions.kotlinVersion} (*) - | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.5.30 -> ${buildOptions.kotlinVersion} - | - """.trimMargin() + | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 -> ${buildOptions.kotlinVersion} + """.trimMargin().normalizeLineEndings() ) } } } @JvmGradlePluginTests - @DisplayName("stdlib-jdk7, stdlib-jdk8 substitution with stdlib:1.8+ in Kotlin DSL") + @DisplayName("alignment in Kotlin DSL") @GradleTest - fun stdlibJdkVariantsSubstitutionKotlinDsl(gradleVersion: GradleVersion) { + fun stdlibJdkAlignmentKotlinDsl(gradleVersion: GradleVersion) { project("sourceSetsKotlinDsl", gradleVersion) { buildGradleKts.appendText( """ @@ -133,19 +132,17 @@ class StdlibAlignmentIT : KGPBaseTest() { """ |\--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2 | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2 - | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 -> org.jetbrains.kotlin:kotlin-stdlib:${buildOptions.kotlinVersion} (*) - | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.5.30 -> ${buildOptions.kotlinVersion} - | - """.trimMargin() + | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30 -> ${buildOptions.kotlinVersion} + """.trimMargin().normalizeLineEndings() ) } } } @JvmGradlePluginTests - @DisplayName("KT-54653: stdlib-jdk7, jdk8 substitution should not work for unrelated configuration") + @DisplayName("KT-54653: alignment should not work for unrelated configuration") @GradleTest - fun stdlibJdkVariantsSubstitutionOnlyConfiguration(gradleVersion: GradleVersion) { + fun stdlibJdkAlignmentUnrelatedConfigurations(gradleVersion: GradleVersion) { project("simpleProject", gradleVersion) { buildGradle.modify { """ @@ -169,16 +166,16 @@ class StdlibAlignmentIT : KGPBaseTest() { |\--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20 -> org.jetbrains.kotlin:kotlin-stdlib:1.7.20 | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.7.20 | \--- org.jetbrains:annotations:13.0 - """.trimMargin() + """.trimMargin().normalizeLineEndings() ) } } } @JvmGradlePluginTests - @DisplayName("KT-54653: stdlib-jdk7, jdk8 substitution works for complex resolvable configurations hierarchy") + @DisplayName("KT-54653: alignment works for complex resolvable configurations hierarchy") @GradleTest - fun stdlibJdkVariantSubstitutionComplexResolvableConfiguration(gradleVersion: GradleVersion) { + fun stdlibJdkAlignmentComplexResolvableConfiguration(gradleVersion: GradleVersion) { project("simpleProject", gradleVersion) { buildGradle.modify { """ @@ -196,7 +193,7 @@ class StdlibAlignmentIT : KGPBaseTest() { | |dependencies { | specificDeps "org.jetbrains.kotlin:kotlin-stdlib:${buildOptions.kotlinVersion}" - | // brings transitevly older stdlib-jdk7,8 dependencies + | // brings transitively older stdlib-jdk7,8 dependencies | specificDepsChild "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" |} """.trimMargin() @@ -222,4 +219,50 @@ class StdlibAlignmentIT : KGPBaseTest() { } } } + + @JvmGradlePluginTests + @DisplayName("KT-54703: JPMS projects with dependency on kotlin.stdlib.jdk8 work as expected") + @JdkVersions(versions = [JavaVersion.VERSION_11]) + @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_0) + @GradleWithJdkTest + fun alignmentWorksCorrectlyForJPMS( + gradleVersion: GradleVersion, + providedJdk: JdkVersions.ProvidedJdk + ) { + project( + "jpmsProject", + gradleVersion, + buildJdk = providedJdk.location + ) { + subProject("list").buildGradleKts.appendText( + """ + | + |dependencies { + | api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20") + |} + """.trimMargin() + ) + subProject("list").javaSourcesDir() + .resolve("module-info.java") + .modify { + val lines = it.lines() + """ + |${lines.first()} + | requires transitive kotlin.stdlib.jdk8; + |${lines.drop(1).joinToString(separator = System.lineSeparator())} + """.trimMargin() + } + + subProject("application").buildGradleKts.appendText( + """ + | + |dependencies { + | implementation("org.jetbrains.kotlin:kotlin-stdlib") + |} + """.trimMargin() + ) + + build(":application:assemble") + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/assertionsUtils.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/assertionsUtils.kt index 0b8340226d6..20ce7711ea0 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/assertionsUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/assertionsUtils.kt @@ -18,3 +18,5 @@ internal fun BuildResult.printBuildOutput() { """.trimMargin() ) } + +internal fun String.normalizeLineEndings(): String = replace("\n", System.lineSeparator()) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/build.gradle.kts new file mode 100644 index 00000000000..5f598942853 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + application +} + +dependencies { + implementation(project(":utilities")) +} + +application { + mainModule.set("org.gradle.sample.app") + mainClass.set("org.gradle.sample.app.Main") +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/module-info.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/module-info.java new file mode 100644 index 00000000000..9456a8b465c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module org.gradle.sample.app { + exports org.gradle.sample.app; + requires org.gradle.sample.utilities; +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/Main.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/Main.java new file mode 100644 index 00000000000..a3770f5f0d5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/Main.java @@ -0,0 +1,15 @@ +package org.gradle.sample.app; + +import org.gradle.sample.list.LinkedList; + +import static org.gradle.sample.utilities.StringUtils.join; +import static org.gradle.sample.utilities.StringUtils.split; +import static org.gradle.sample.app.MessageUtils.getMessage; + +public class Main { + public static void main(String[] args) { + LinkedList tokens; + tokens = split(getMessage()); + System.out.println(join(tokens)); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/MessageUtils.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/MessageUtils.java new file mode 100644 index 00000000000..e5df2f9799e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/main/java/org/gradle/sample/app/MessageUtils.java @@ -0,0 +1,7 @@ +package org.gradle.sample.app; + +class MessageUtils { + public static String getMessage() { + return "Hello, World!"; + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/test/java/org/gradle/sample/app/MessageUtilsTest.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/test/java/org/gradle/sample/app/MessageUtilsTest.java new file mode 100644 index 00000000000..c9b17b022a3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/application/src/test/java/org/gradle/sample/app/MessageUtilsTest.java @@ -0,0 +1,11 @@ +package org.gradle.sample.app; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MessageUtilsTest { + @Test public void testGetMessage() { + assertEquals("Hello, World!", MessageUtils.getMessage()); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/build.gradle.kts new file mode 100644 index 00000000000..8bd0d74957b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/build.gradle.kts @@ -0,0 +1,6 @@ +subprojects { + repositories { + mavenLocal() + mavenCentral() + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/build.gradle.kts new file mode 100644 index 00000000000..82204b48400 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/build.gradle.kts @@ -0,0 +1,4 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + `java` +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/module-info.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/module-info.java new file mode 100644 index 00000000000..0d9079ed789 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module org.gradle.sample.list { + exports org.gradle.sample.list; +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/org/gradle/sample/list/LinkedList.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/org/gradle/sample/list/LinkedList.java new file mode 100644 index 00000000000..a6c576e6ba7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/list/src/main/java/org/gradle/sample/list/LinkedList.java @@ -0,0 +1,78 @@ +package org.gradle.sample.list; + +public class LinkedList { + private Node head; + + public void add(String element) { + Node newNode = new Node(element); + + Node it = tail(head); + if (it == null) { + head = newNode; + } else { + it.next = newNode; + } + } + + private static Node tail(Node head) { + Node it; + + for (it = head; it != null && it.next != null; it = it.next) {} + + return it; + } + + public boolean remove(String element) { + boolean result = false; + Node previousIt = null; + Node it = null; + for (it = head; !result && it != null; previousIt = it, it = it.next) { + if (0 == element.compareTo(it.data)) { + result = true; + unlink(previousIt, it); + break; + } + } + + return result; + } + + private void unlink(Node previousIt, Node currentIt) { + if (currentIt == head) { + head = currentIt.next; + } else { + previousIt.next = currentIt.next; + } + } + + public int size() { + int size = 0; + + for (Node it = head; it != null; ++size, it = it.next) {} + + return size; + } + + public String get(int index) { + Node it = head; + while (index > 0 && it != null) { + it = it.next; + index--; + } + + if (it == null) { + throw new IndexOutOfBoundsException("Index is out of range"); + } + + return it.data; + } + + private static class Node { + final String data; + Node next; + + Node(String data) { + this.data = data; + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/settings.gradle.kts new file mode 100644 index 00000000000..73df6129fc4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "modules-multi-project" +include("application", "list", "utilities") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/build.gradle.kts new file mode 100644 index 00000000000..62c1abe3619 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("org.jetbrains.kotlin.jvm") +} + +dependencies { + api(project(":list")) +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/module-info.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/module-info.java new file mode 100644 index 00000000000..e613cc603fb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module org.gradle.sample.utilities { + requires transitive org.gradle.sample.list; + exports org.gradle.sample.utilities; +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/JoinUtils.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/JoinUtils.java new file mode 100644 index 00000000000..45365d35a95 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/JoinUtils.java @@ -0,0 +1,17 @@ +package org.gradle.sample.utilities; + +import org.gradle.sample.list.LinkedList; + +class JoinUtils { + public static String join(LinkedList source) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < source.size(); ++i) { + if (result.length() > 0) { + result.append(" "); + } + result.append(source.get(i)); + } + + return result.toString(); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/SplitUtils.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/SplitUtils.java new file mode 100644 index 00000000000..4016d850f1c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/SplitUtils.java @@ -0,0 +1,36 @@ +package org.gradle.sample.utilities; + +import org.gradle.sample.list.LinkedList; + +class SplitUtils { + public static LinkedList split(String source) { + int lastFind = 0; + int currentFind = 0; + LinkedList result = new LinkedList(); + + while ((currentFind = source.indexOf(" ", lastFind)) != -1) { + String token = source.substring(lastFind); + if (currentFind != -1) { + token = token.substring(0, currentFind - lastFind); + } + + addIfValid(token, result); + lastFind = currentFind + 1; + } + + String token = source.substring(lastFind); + addIfValid(token, result); + + return result; + } + + private static void addIfValid(String token, LinkedList list) { + if (isTokenValid(token)) { + list.add(token); + } + } + + private static boolean isTokenValid(String token) { + return !token.isEmpty(); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/StringUtils.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/StringUtils.java new file mode 100644 index 00000000000..72a33b58b26 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/jpmsProject/utilities/src/main/java/org/gradle/sample/utilities/StringUtils.java @@ -0,0 +1,13 @@ +package org.gradle.sample.utilities; + +import org.gradle.sample.list.LinkedList; + +public class StringUtils { + public static String join(LinkedList source) { + return JoinUtils.join(source); + } + + public static LinkedList split(String source) { + return SplitUtils.split(source); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt index b0b1677348c..e06902f5af0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt @@ -47,8 +47,8 @@ internal fun customizeKotlinDependencies(project: Project) { coreLibrariesVersion ) - if (propertiesProvider.stdlibJdkVariantsSubstitution) { - project.configurations.configureStdlibSubstitution() + if (propertiesProvider.stdlibJdkVariantsVersionAlignment) { + project.configurations.configureStdlibVersionAlignment() } excludeStdlibAndKotlinTestCommonFromPlatformCompilations(project) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt index ff8ef7dceed..5497de231b9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/stdlibDependencyManagement.kt @@ -51,10 +51,10 @@ internal fun Project.configureStdlibDefaultDependency( } /** - * Replacing kotlin-stdlib-jdk8 and kotlin-stdlib-jdk7 artifacts with kotlin-stdlib + * Aligning kotlin-stdlib-jdk8 and kotlin-stdlib-jdk7 dependencies versions with kotlin-stdlib (or kotlin-stdlib-jdk7) * when project stdlib version is >= 1.8.0 */ -internal fun ConfigurationContainer.configureStdlibSubstitution() = all { configuration -> +internal fun ConfigurationContainer.configureStdlibVersionAlignment() = all { configuration -> configuration.withDependencies { dependencySet -> dependencySet .withType() @@ -64,32 +64,32 @@ internal fun ConfigurationContainer.configureStdlibSubstitution() = all { config dependency.version != null && SemVer.from(dependency.version!!) >= kotlin180Version ) { - if (configuration.isCanBeResolved) configuration.substitudeStdlibJvmVariants(dependency) + if (configuration.isCanBeResolved) configuration.alignStdlibJvmVariantVersions(dependency) // dependency substitution only works for resolvable configuration, // so we need to find all configuration that extends current one filter { it.isCanBeResolved && it.hierarchy.contains(configuration) }.forEach { - it.substitudeStdlibJvmVariants(dependency) + it.alignStdlibJvmVariantVersions(dependency) } } } } } -private fun Configuration.substitudeStdlibJvmVariants( +private fun Configuration.alignStdlibJvmVariantVersions( kotlinStdlibDependency: ExternalDependency ) { resolutionStrategy.dependencySubstitution { if (kotlinStdlibDependency.name != "kotlin-stdlib-jdk7") { it.substitute(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk7")) - .using(it.module("org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdlibDependency.version}")) + .using(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlinStdlibDependency.version}")) .because("kotlin-stdlib-jdk7 is now part of kotlin-stdlib") } it.substitute(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk8")) - .using(it.module("org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdlibDependency.version}")) + .using(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinStdlibDependency.version}")) .because("kotlin-stdlib-jdk8 is now part of kotlin-stdlib") } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index bdba89bc2de..115e90e3677 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_HIERARCHICAL_STRUCTURE_SUPPORT import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_DEFAULT_DEPENDENCY -import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_JDK_VARIANTS_SUBSTITUTION +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_JDK_VARIANTS_VERSION_ALIGNMENT import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinIrJsGeneratedTSValidationStrategy import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrOutputGranularity @@ -403,8 +403,8 @@ internal class PropertiesProvider private constructor(private val project: Proje val stdlibDefaultDependency: Boolean get() = booleanProperty(KOTLIN_STDLIB_DEFAULT_DEPENDENCY) ?: true - val stdlibJdkVariantsSubstitution: Boolean - get() = booleanProperty(KOTLIN_STDLIB_JDK_VARIANTS_SUBSTITUTION) ?: true + val stdlibJdkVariantsVersionAlignment: Boolean + get() = booleanProperty(KOTLIN_STDLIB_JDK_VARIANTS_VERSION_ALIGNMENT) ?: true val kotlinTestInferJvmVariant: Boolean get() = booleanProperty("kotlin.test.infer.jvm.variant") ?: true @@ -478,7 +478,7 @@ internal class PropertiesProvider private constructor(private val project: Proje object PropertyNames { const val KOTLIN_STDLIB_DEFAULT_DEPENDENCY = "kotlin.stdlib.default.dependency" - const val KOTLIN_STDLIB_JDK_VARIANTS_SUBSTITUTION = "kotlin.stdlib.jdk.variants.substitution" + const val KOTLIN_STDLIB_JDK_VARIANTS_VERSION_ALIGNMENT = "kotlin.stdlib.jdk.variants.version.alignment" const val KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA = "kotlin.mpp.enableGranularSourceSetsMetadata" const val KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION = "kotlin.mpp.enableCInteropCommonization" const val KOTLIN_MPP_HIERARCHICAL_STRUCTURE_BY_DEFAULT = "kotlin.internal.mpp.hierarchicalStructureByDefault"