From 6c94e4c9f940238827a0ab9f6fb1e3c8efe1a8f9 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Mon, 20 Nov 2023 16:48:40 +0100 Subject: [PATCH 01/18] Remove the module-info.class from kotlinx-coroutines-debug This module-info taken from bytebuddy was incorrectly picked up as the module info for `kotlinx-coroutines-debug` --- kotlinx-coroutines-debug/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/kotlinx-coroutines-debug/build.gradle b/kotlinx-coroutines-debug/build.gradle index 42d0b8d0f0..076a566a4f 100644 --- a/kotlinx-coroutines-debug/build.gradle +++ b/kotlinx-coroutines-debug/build.gradle @@ -48,6 +48,7 @@ def shadowJarTask = shadowJar { classifier null // Shadow only byte buddy, do not package kotlin stdlib configurations = [project.configurations.shadowDeps] + exclude('META-INF/versions/9/module-info.class') relocate('net.bytebuddy', 'kotlinx.coroutines.repackaged.net.bytebuddy') manifest { From 8f96fe18ad314b0160b7d4cdcbb24bc855f01a03 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Tue, 21 Nov 2023 12:56:32 +0100 Subject: [PATCH 02/18] Add the proper module-info to the debug jar --- kotlinx-coroutines-debug/build.gradle | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle b/kotlinx-coroutines-debug/build.gradle index 076a566a4f..5ce692ba85 100644 --- a/kotlinx-coroutines-debug/build.gradle +++ b/kotlinx-coroutines-debug/build.gradle @@ -45,22 +45,40 @@ jar { } def shadowJarTask = shadowJar { - classifier null // Shadow only byte buddy, do not package kotlin stdlib configurations = [project.configurations.shadowDeps] - exclude('META-INF/versions/9/module-info.class') relocate('net.bytebuddy', 'kotlinx.coroutines.repackaged.net.bytebuddy') + // exclude the module-info.class provided by bytebuddy + exclude("META-INF/versions/9/module-info.class") +} +// adapted from +// There doesn't seem to be a way to ask the shadow jar to contain the `module-info.class` provided by us and not +// the one provided by bytebuddy. So, this is done in two steps: `shadowJarTask` excludes the module-info from +// bytebuddy, and this task creates another jar file, this time one that has the correct module-info. +def shadowJarWithCorrectModuleInfoTask = task shadowJarWithCorrectModuleInfo(type: Jar) { + group 'shadow' + from zipTree(shadowJarTask.archiveFile) + from(tasks.compileModuleInfoJava) { + // Include **only** file we are interested in as JavaCompile output also contains some tmp files + include("module-info.class") + into("META-INF/versions/9/") + } + duplicatesStrategy = DuplicatesStrategy.FAIL + archiveBaseName.set(shadowJarTask.archiveBaseName) + archiveVersion.set(shadowJarTask.archiveVersion) + classifier null manifest { attributes "Premain-Class": "kotlinx.coroutines.debug.AgentPremain" attributes "Can-Redefine-Classes": "true" + attributes "Multi-Release": "true" } } configurations { artifacts { - add("apiElements", shadowJarTask) - add("runtimeElements", shadowJarTask) + add("apiElements", shadowJarWithCorrectModuleInfoTask) + add("runtimeElements", shadowJarWithCorrectModuleInfoTask) } } From 39925f4720cac90aee5fb086dc865a847fd1508d Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 22 Nov 2023 15:22:07 +0100 Subject: [PATCH 03/18] Rewrite kotlinx-coroutines-debug/build.gradle to build.gradle.kts Also try to fix the shadow jar being published --- build.gradle | 35 +----- buildSrc/src/main/kotlin/VersionFile.kt | 24 ++++ .../version-file-conventions.gradle.kts | 11 ++ gradle/publish.gradle | 4 - kotlinx-coroutines-debug/build.gradle | 92 --------------- kotlinx-coroutines-debug/build.gradle.kts | 111 ++++++++++++++++++ 6 files changed, 147 insertions(+), 130 deletions(-) create mode 100644 buildSrc/src/main/kotlin/VersionFile.kt create mode 100644 buildSrc/src/main/kotlin/version-file-conventions.gradle.kts delete mode 100644 kotlinx-coroutines-debug/build.gradle create mode 100644 kotlinx-coroutines-debug/build.gradle.kts diff --git a/build.gradle b/build.gradle index 2b00f602e3..f6c4cf31c7 100644 --- a/build.gradle +++ b/build.gradle @@ -177,6 +177,7 @@ configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != core apply plugin: "bom-conventions" apply plugin: "java-modularity-conventions" +apply plugin: "version-file-conventions" if (build_snapshot_train) { println "Hacking test tasks, removing stress and flaky tests" @@ -252,40 +253,6 @@ configure(subprojects.findAll { !unpublished.contains(it.name) }) { } } } - - def thisProject = it - if (thisProject.name in sourceless) { - return - } - - def versionFileTask = thisProject.tasks.register("versionFileTask") { - def name = thisProject.name.replace("-", "_") - def versionFile = thisProject.layout.buildDirectory.file("${name}.version") - it.outputs.file(versionFile) - - it.doLast { - versionFile.get().asFile.text = version.toString() - } - } - - List jarTasks - if (isMultiplatform(it)) { - jarTasks = ["jvmJar"] - } else if (it.name == "kotlinx-coroutines-debug") { - // We shadow debug module instead of just packaging it - jarTasks = ["shadowJar"] - } else { - jarTasks = ["jar"] - } - - for (name in jarTasks) { - thisProject.tasks.named(name, Jar) { - it.dependsOn versionFileTask - it.from(versionFileTask) { - into("META-INF") - } - } - } } // Report Kotlin compiler version when building project diff --git a/buildSrc/src/main/kotlin/VersionFile.kt b/buildSrc/src/main/kotlin/VersionFile.kt new file mode 100644 index 0000000000..d4530379ff --- /dev/null +++ b/buildSrc/src/main/kotlin/VersionFile.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import org.gradle.api.* +import org.gradle.api.tasks.* +import org.gradle.kotlin.dsl.* + +object VersionFile { + fun configure(project: Project, jarTask: AbstractCopyTask) = with(project) { + val versionFileTask by tasks.register("versionFileTask") { + val name = project.name.replace('-', '_') + val versionFile = project.layout.buildDirectory.file("$name.version") + outputs.file(versionFile) + doLast { + versionFile.get().asFile.writeText(project.version.toString()) + } + } + jarTask.dependsOn(versionFileTask) + jarTask.from(versionFileTask) { + into("META-INF") + } + } +} diff --git a/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts new file mode 100644 index 0000000000..3217656f2c --- /dev/null +++ b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts @@ -0,0 +1,11 @@ +import org.gradle.api.tasks.bundling.* + +/* `kotlinx-coroutines-debug` configures `VersionFile` on its own when the corresponding task is created. */ +val invalidModules = listOf("kotlinx-coroutines-debug") + +configure(subprojects.filter { + !unpublished.contains(it.name) && !invalidModules.contains(it.name) && it.name !in sourceless +}) { + val jarTask = tasks.withType(Jar::class.java).findByName(if (isMultiplatform) { "jvmJar" } else { "jar" })!! + VersionFile.configure(this, jarTask) +} diff --git a/gradle/publish.gradle b/gradle/publish.gradle index f3b1561dde..8907e0d03e 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -15,10 +15,6 @@ def isMultiplatform = project.name == "kotlinx-coroutines-core" || project.name def isBom = project.name == "kotlinx-coroutines-bom" if (!isBom) { - if (project.name == "kotlinx-coroutines-debug") { - apply plugin: "com.github.johnrengelman.shadow" - } - // empty xxx-javadoc.jar task javadocJar(type: Jar) { archiveClassifier = 'javadoc' diff --git a/kotlinx-coroutines-debug/build.gradle b/kotlinx-coroutines-debug/build.gradle deleted file mode 100644 index 5ce692ba85..0000000000 --- a/kotlinx-coroutines-debug/build.gradle +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -apply plugin: "com.github.johnrengelman.shadow" - -// apply plugin to use autocomplete for Kover DSL -apply plugin: 'org.jetbrains.kotlinx.kover' - -configurations { - shadowDeps // shaded dependencies, not included into the resulting .pom file - compileOnly.extendsFrom(shadowDeps) - runtimeOnly.extendsFrom(shadowDeps) -} - -dependencies { - compileOnly "junit:junit:$junit_version" - compileOnly "org.junit.jupiter:junit-jupiter-api:$junit5_version" - testImplementation "org.junit.jupiter:junit-jupiter-engine:$junit5_version" - testImplementation "org.junit.platform:junit-platform-testkit:1.7.0" - shadowDeps "net.bytebuddy:byte-buddy:$byte_buddy_version" - shadowDeps "net.bytebuddy:byte-buddy-agent:$byte_buddy_version" - compileOnly "io.projectreactor.tools:blockhound:$blockhound_version" - testImplementation "io.projectreactor.tools:blockhound:$blockhound_version" - testImplementation "com.google.code.gson:gson:2.8.6" - api "net.java.dev.jna:jna:$jna_version" - api "net.java.dev.jna:jna-platform:$jna_version" -} - -java { - /* This is needed to be able to run JUnit5 tests. Otherwise, Gradle complains that it can't find the - JVM1.6-compatible version of the `junit-jupiter-api` artifact. */ - disableAutoTargetJvm() -} - -// This is required for BlockHound tests to work, see https://github.com/Kotlin/kotlinx.coroutines/issues/3701 -tasks.withType(Test).configureEach { - if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { - jvmArgs += ["-XX:+AllowRedefinitionToAddDeleteMethods"] - } -} - -jar { - setEnabled(false) -} - -def shadowJarTask = shadowJar { - // Shadow only byte buddy, do not package kotlin stdlib - configurations = [project.configurations.shadowDeps] - relocate('net.bytebuddy', 'kotlinx.coroutines.repackaged.net.bytebuddy') - // exclude the module-info.class provided by bytebuddy - exclude("META-INF/versions/9/module-info.class") -} - -// adapted from -// There doesn't seem to be a way to ask the shadow jar to contain the `module-info.class` provided by us and not -// the one provided by bytebuddy. So, this is done in two steps: `shadowJarTask` excludes the module-info from -// bytebuddy, and this task creates another jar file, this time one that has the correct module-info. -def shadowJarWithCorrectModuleInfoTask = task shadowJarWithCorrectModuleInfo(type: Jar) { - group 'shadow' - from zipTree(shadowJarTask.archiveFile) - from(tasks.compileModuleInfoJava) { - // Include **only** file we are interested in as JavaCompile output also contains some tmp files - include("module-info.class") - into("META-INF/versions/9/") - } - duplicatesStrategy = DuplicatesStrategy.FAIL - archiveBaseName.set(shadowJarTask.archiveBaseName) - archiveVersion.set(shadowJarTask.archiveVersion) - classifier null - manifest { - attributes "Premain-Class": "kotlinx.coroutines.debug.AgentPremain" - attributes "Can-Redefine-Classes": "true" - attributes "Multi-Release": "true" - } -} - -configurations { - artifacts { - add("apiElements", shadowJarWithCorrectModuleInfoTask) - add("runtimeElements", shadowJarWithCorrectModuleInfoTask) - } -} - -koverReport { - filters { - excludes { - // Never used, safety mechanism - classes("kotlinx.coroutines.debug.internal.NoOpProbesKt") - } - } -} diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts new file mode 100644 index 0000000000..445ca6c68c --- /dev/null +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -0,0 +1,111 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.* + +/* + * Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +apply(plugin = "com.github.johnrengelman.shadow") + +// apply plugin to use autocomplete for Kover DSL +apply(plugin = "org.jetbrains.kotlinx.kover") + +configurations { + val shadowDeps by creating // shaded dependencies, not included into the resulting .pom file + compileOnly.get().extendsFrom(shadowDeps) + runtimeOnly.get().extendsFrom(shadowDeps) +} + +val junit_version by properties +val junit5_version by properties +val byte_buddy_version by properties +val blockhound_version by properties +val jna_version by properties + +dependencies { + compileOnly("junit:junit:$junit_version") + compileOnly("org.junit.jupiter:junit-jupiter-api:$junit5_version") + testImplementation("org.junit.jupiter:junit-jupiter-engine:$junit5_version") + testImplementation("org.junit.platform:junit-platform-testkit:1.7.0") + add("shadowDeps", "net.bytebuddy:byte-buddy:$byte_buddy_version") + add("shadowDeps", "net.bytebuddy:byte-buddy-agent:$byte_buddy_version") + compileOnly("io.projectreactor.tools:blockhound:$blockhound_version") + testImplementation("io.projectreactor.tools:blockhound:$blockhound_version") + testImplementation("com.google.code.gson:gson:2.8.6") + api("net.java.dev.jna:jna:$jna_version") + api("net.java.dev.jna:jna-platform:$jna_version") +} + +java { + /* This is needed to be able to run JUnit5 tests. Otherwise, Gradle complains that it can't find the + JVM1.6-compatible version of the `junit-jupiter-api` artifact. */ + disableAutoTargetJvm() +} + +// This is required for BlockHound tests to work, see https://github.com/Kotlin/kotlinx.coroutines/issues/3701 +tasks.withType().configureEach { + if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { + jvmArgs("-XX:+AllowRedefinitionToAddDeleteMethods") + } +} + +val jar by tasks.getting(Jar::class) { + enabled = false +} + +val shadowJar by tasks.getting(ShadowJar::class) { + // Shadow only byte buddy, do not package kotlin stdlib + configurations = listOf(project.configurations["shadowDeps"]) + relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") + // exclude the module-info.class provided by bytebuddy + exclude("META-INF/versions/9/module-info.class") +} + +// adapted from +// There doesn't seem to be a way to ask the shadow jar to contain the `module-info.class` provided by us and not +// the one provided by bytebuddy. So, this is done in two steps: `shadowJarTask` excludes the module-info from +// bytebuddy, and this task creates another jar file, this time one that has the correct module-info. +val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) { + group = "shadow" + from(zipTree(shadowJar.archiveFile)) + from(tasks.compileModuleInfoJava) { + // Include **only** file we are interested in as JavaCompile output also contains some tmp files + include("module-info.class") + into("META-INF/versions/9/") + } + duplicatesStrategy = DuplicatesStrategy.FAIL + archiveBaseName.set(jar.archiveBaseName) + archiveVersion.set(jar.archiveVersion) + archiveClassifier.set(jar.archiveClassifier) + manifest { + attributes(mapOf( + "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain", + "Can-Redefine-Classes" to "true", + "Multi-Release" to "true" + )) + } +} + +tasks.getByName("publishMavenPublicationToMavenLocal") { + dependsOn(shadowJarWithCorrectModuleInfo) +} + +VersionFile.configure(project, shadowJarWithCorrectModuleInfo.get()) + +configurations.all { + outgoing.artifacts.removeIf { + val dependencies = it.buildDependencies.getDependencies(null) + dependencies.contains(jar) || dependencies.contains(shadowJar) + } + if (name == "apiElements" || name == "runtimeElements") { + outgoing.artifact(shadowJarWithCorrectModuleInfo) + } +} + +koverReport { + filters { + excludes { + // Never used, safety mechanism + classes("kotlinx.coroutines.debug.internal.NoOpProbesKt") + } + } +} From e945903bb9846253261d290cbe9cfb481a7f74c9 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 22 Nov 2023 16:32:22 +0100 Subject: [PATCH 04/18] Clearer artifact management --- kotlinx-coroutines-debug/build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 445ca6c68c..9620ce8080 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -92,11 +92,11 @@ tasks.getByName("publishMavenPublicationToMavenLocal") { VersionFile.configure(project, shadowJarWithCorrectModuleInfo.get()) configurations.all { - outgoing.artifacts.removeIf { - val dependencies = it.buildDependencies.getDependencies(null) - dependencies.contains(jar) || dependencies.contains(shadowJar) - } - if (name == "apiElements" || name == "runtimeElements") { + // we're not interested at all in the output of the shadowJar task; it's just an intermediate stage + outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(shadowJar) } + // if something wants a `jar` to be published, we want to publish the `shadowJarWithCorrectModuleInfo` instead + if (outgoing.artifacts.buildDependencies.getDependencies(null).contains(jar)) { + outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) } outgoing.artifact(shadowJarWithCorrectModuleInfo) } } From 2405ea4b9b62c8c7d20f21ec5c09e0f44f02381e Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 22 Nov 2023 16:37:31 +0100 Subject: [PATCH 05/18] Misplaced import --- kotlinx-coroutines-debug/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 9620ce8080..a570167e21 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -1,9 +1,9 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.* - /* * Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ +import com.github.jengelman.gradle.plugins.shadow.tasks.* + apply(plugin = "com.github.johnrengelman.shadow") // apply plugin to use autocomplete for Kover DSL From d0776e819854227b56d958003cd1f360a829512d Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 22 Nov 2023 16:45:02 +0100 Subject: [PATCH 06/18] Remove an extraneous import --- gradle/publish.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/gradle/publish.gradle b/gradle/publish.gradle index 8907e0d03e..9984ae8e70 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -2,8 +2,6 @@ * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ -import org.gradle.util.VersionNumber - // Configures publishing of Maven artifacts to Maven Central apply plugin: 'maven-publish' From ed33602d86eababa9554661d50711eb189b1e9a6 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy <52952525+dkhalanskyjb@users.noreply.github.com> Date: Fri, 24 Nov 2023 14:41:31 +0300 Subject: [PATCH 07/18] Update buildSrc/src/main/kotlin/VersionFile.kt Co-authored-by: Vsevolod Tolstopyatov --- buildSrc/src/main/kotlin/VersionFile.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildSrc/src/main/kotlin/VersionFile.kt b/buildSrc/src/main/kotlin/VersionFile.kt index d4530379ff..b2ce501c7a 100644 --- a/buildSrc/src/main/kotlin/VersionFile.kt +++ b/buildSrc/src/main/kotlin/VersionFile.kt @@ -6,6 +6,10 @@ import org.gradle.api.* import org.gradle.api.tasks.* import org.gradle.kotlin.dsl.* +/** + * Adds 'module_name.version' file to the project's JAR META-INF + * for the better toolability. See #2941 + */ object VersionFile { fun configure(project: Project, jarTask: AbstractCopyTask) = with(project) { val versionFileTask by tasks.register("versionFileTask") { From e9916a6969fc500005284d22561dd4e090fdcff3 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Fri, 24 Nov 2023 12:56:11 +0100 Subject: [PATCH 08/18] Attempt configuration avoidance --- buildSrc/src/main/kotlin/VersionFile.kt | 11 ++++++----- .../main/kotlin/version-file-conventions.gradle.kts | 10 ++++++++-- kotlinx-coroutines-debug/build.gradle.kts | 5 +++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/main/kotlin/VersionFile.kt b/buildSrc/src/main/kotlin/VersionFile.kt index b2ce501c7a..4de57a2777 100644 --- a/buildSrc/src/main/kotlin/VersionFile.kt +++ b/buildSrc/src/main/kotlin/VersionFile.kt @@ -4,15 +4,14 @@ import org.gradle.api.* import org.gradle.api.tasks.* -import org.gradle.kotlin.dsl.* /** * Adds 'module_name.version' file to the project's JAR META-INF * for the better toolability. See #2941 */ object VersionFile { - fun configure(project: Project, jarTask: AbstractCopyTask) = with(project) { - val versionFileTask by tasks.register("versionFileTask") { + fun registerVersionFileTask(project: Project): TaskProvider = with(project) { + tasks.register("versionFileTask") { val name = project.name.replace('-', '_') val versionFile = project.layout.buildDirectory.file("$name.version") outputs.file(versionFile) @@ -20,8 +19,10 @@ object VersionFile { versionFile.get().asFile.writeText(project.version.toString()) } } - jarTask.dependsOn(versionFileTask) - jarTask.from(versionFileTask) { + } + + fun fromVersionFile(target: AbstractCopyTask, versionFileTask: TaskProvider) { + target.from(versionFileTask) { into("META-INF") } } diff --git a/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts index 3217656f2c..fc38eef712 100644 --- a/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts @@ -6,6 +6,12 @@ val invalidModules = listOf("kotlinx-coroutines-debug") configure(subprojects.filter { !unpublished.contains(it.name) && !invalidModules.contains(it.name) && it.name !in sourceless }) { - val jarTask = tasks.withType(Jar::class.java).findByName(if (isMultiplatform) { "jvmJar" } else { "jar" })!! - VersionFile.configure(this, jarTask) + val project = this + val jarTaskName = if (isMultiplatform) "jvmJar" else "jar" + val versionFileTask = VersionFile.registerVersionFileTask(project) + tasks.withType(Jar::class.java).configureEach { + if (name == jarTaskName) { + VersionFile.fromVersionFile(this, versionFileTask) + } + } } diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index a570167e21..8795b98671 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -60,6 +60,8 @@ val shadowJar by tasks.getting(ShadowJar::class) { exclude("META-INF/versions/9/module-info.class") } +val versionFileTask = VersionFile.registerVersionFileTask(project) + // adapted from // There doesn't seem to be a way to ask the shadow jar to contain the `module-info.class` provided by us and not // the one provided by bytebuddy. So, this is done in two steps: `shadowJarTask` excludes the module-info from @@ -83,14 +85,13 @@ val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) { "Multi-Release" to "true" )) } + VersionFile.fromVersionFile(this, versionFileTask) } tasks.getByName("publishMavenPublicationToMavenLocal") { dependsOn(shadowJarWithCorrectModuleInfo) } -VersionFile.configure(project, shadowJarWithCorrectModuleInfo.get()) - configurations.all { // we're not interested at all in the output of the shadowJar task; it's just an intermediate stage outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(shadowJar) } From e11c8857f204afac10c422357346ea1934ef1b48 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy <52952525+dkhalanskyjb@users.noreply.github.com> Date: Fri, 24 Nov 2023 15:55:42 +0300 Subject: [PATCH 09/18] Update kotlinx-coroutines-debug/build.gradle.kts Co-authored-by: Titouan BION --- kotlinx-coroutines-debug/build.gradle.kts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 8795b98671..b201c6611b 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -9,10 +9,14 @@ apply(plugin = "com.github.johnrengelman.shadow") // apply plugin to use autocomplete for Kover DSL apply(plugin = "org.jetbrains.kotlinx.kover") -configurations { - val shadowDeps by creating // shaded dependencies, not included into the resulting .pom file - compileOnly.get().extendsFrom(shadowDeps) - runtimeOnly.get().extendsFrom(shadowDeps) +configurations{ + val shadowDeps by creating + compileOnly.configure { + extendsFrom(shadowDeps) + } + runtimeOnly.configure { + extendsFrom(shadowDeps) + } } val junit_version by properties From 34a8c5e61d7fb6cc1b08ced7b5f9af0f4ae4ade5 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy <52952525+dkhalanskyjb@users.noreply.github.com> Date: Fri, 24 Nov 2023 15:55:56 +0300 Subject: [PATCH 10/18] Update kotlinx-coroutines-debug/build.gradle.kts Co-authored-by: Titouan BION --- kotlinx-coroutines-debug/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index b201c6611b..4e699d16f8 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -92,7 +92,7 @@ val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) { VersionFile.fromVersionFile(this, versionFileTask) } -tasks.getByName("publishMavenPublicationToMavenLocal") { +tasks.named("publishMavenPublicationToMavenLocal") { dependsOn(shadowJarWithCorrectModuleInfo) } From 9bfbd9e227e078d6e117754594918313dac52412 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy <52952525+dkhalanskyjb@users.noreply.github.com> Date: Fri, 24 Nov 2023 15:57:46 +0300 Subject: [PATCH 11/18] Update kotlinx-coroutines-debug/build.gradle.kts Co-authored-by: Titouan BION --- kotlinx-coroutines-debug/build.gradle.kts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 4e699d16f8..77673f6970 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -4,10 +4,10 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.* -apply(plugin = "com.github.johnrengelman.shadow") - -// apply plugin to use autocomplete for Kover DSL -apply(plugin = "org.jetbrains.kotlinx.kover") +plugins { + id("com.github.johnrengelman.shadow") + id("org.jetbrains.kotlinx.kover") // apply plugin to use autocomplete for Kover DSL +} configurations{ val shadowDeps by creating From 3a83b008046dc9381440c505c90459d37b9d6054 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Fri, 24 Nov 2023 14:02:54 +0100 Subject: [PATCH 12/18] Gradle optimization --- buildSrc/src/main/kotlin/VersionFile.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/kotlin/VersionFile.kt b/buildSrc/src/main/kotlin/VersionFile.kt index 4de57a2777..ef0ef0faa1 100644 --- a/buildSrc/src/main/kotlin/VersionFile.kt +++ b/buildSrc/src/main/kotlin/VersionFile.kt @@ -10,13 +10,13 @@ import org.gradle.api.tasks.* * for the better toolability. See #2941 */ object VersionFile { - fun registerVersionFileTask(project: Project): TaskProvider = with(project) { - tasks.register("versionFileTask") { - val name = project.name.replace('-', '_') - val versionFile = project.layout.buildDirectory.file("$name.version") + fun registerVersionFileTask(project: Project): TaskProvider { + val versionFile = project.layout.buildDirectory.file("${project.name.replace('-', '_')}.version") + val version = project.version.toString() + return project.tasks.register("versionFileTask") { outputs.file(versionFile) doLast { - versionFile.get().asFile.writeText(project.version.toString()) + versionFile.get().asFile.writeText(version) } } } From b6e375cacb2c928fcb6b8c00e7a1a0dc2e5924cb Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Mon, 27 Nov 2023 15:43:58 +0100 Subject: [PATCH 13/18] Fail to avoid creating yet another jar for kotlinx-coroutines-debug --- gradle/publish.gradle | 3 ++ kotlinx-coroutines-debug/build.gradle.kts | 50 +++++++++-------------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/gradle/publish.gradle b/gradle/publish.gradle index 9984ae8e70..d6bee65210 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -13,6 +13,9 @@ def isMultiplatform = project.name == "kotlinx-coroutines-core" || project.name def isBom = project.name == "kotlinx-coroutines-bom" if (!isBom) { + if (project.name == "kotlinx-coroutines-debug") { + apply plugin: "com.github.johnrengelman.shadow" + } // empty xxx-javadoc.jar task javadocJar(type: Jar) { archiveClassifier = 'javadoc' diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 77673f6970..d95e5f7caa 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -56,32 +56,20 @@ val jar by tasks.getting(Jar::class) { enabled = false } +val versionFileTask = VersionFile.registerVersionFileTask(project) + val shadowJar by tasks.getting(ShadowJar::class) { // Shadow only byte buddy, do not package kotlin stdlib configurations = listOf(project.configurations["shadowDeps"]) - relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") - // exclude the module-info.class provided by bytebuddy - exclude("META-INF/versions/9/module-info.class") -} - -val versionFileTask = VersionFile.registerVersionFileTask(project) - -// adapted from -// There doesn't seem to be a way to ask the shadow jar to contain the `module-info.class` provided by us and not -// the one provided by bytebuddy. So, this is done in two steps: `shadowJarTask` excludes the module-info from -// bytebuddy, and this task creates another jar file, this time one that has the correct module-info. -val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) { - group = "shadow" - from(zipTree(shadowJar.archiveFile)) - from(tasks.compileModuleInfoJava) { - // Include **only** file we are interested in as JavaCompile output also contains some tmp files - include("module-info.class") - into("META-INF/versions/9/") + relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") { + this.exclude("META-INF/versions/9/module-info.class") } - duplicatesStrategy = DuplicatesStrategy.FAIL + // // exclude the module-info.class provided by bytebuddy + // exclude("META-INF/versions/9/module-info.class") + archiveClassifier.convention(null as String?) + archiveClassifier.set(null as String?) archiveBaseName.set(jar.archiveBaseName) archiveVersion.set(jar.archiveVersion) - archiveClassifier.set(jar.archiveClassifier) manifest { attributes(mapOf( "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain", @@ -90,19 +78,19 @@ val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) { )) } VersionFile.fromVersionFile(this, versionFileTask) + from(tasks.compileModuleInfoJava) { + // Include **only** file we are interested in as JavaCompile output also contains some tmp files + include("module-info.class") + into("META-INF/versions/9/") + } + duplicatesStrategy = DuplicatesStrategy.FAIL } -tasks.named("publishMavenPublicationToMavenLocal") { - dependsOn(shadowJarWithCorrectModuleInfo) -} - -configurations.all { - // we're not interested at all in the output of the shadowJar task; it's just an intermediate stage - outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(shadowJar) } - // if something wants a `jar` to be published, we want to publish the `shadowJarWithCorrectModuleInfo` instead - if (outgoing.artifacts.buildDependencies.getDependencies(null).contains(jar)) { - outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) } - outgoing.artifact(shadowJarWithCorrectModuleInfo) +configurations { + // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but it's not enough. + artifacts { + add("apiElements", shadowJar) + add("runtimeElements", shadowJar) } } From 8e484d5e2adbee469ea1a878a6c19b14e141e67e Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Tue, 28 Nov 2023 13:12:15 +0100 Subject: [PATCH 14/18] Avoid creating yet another jar for kotlinx-coroutines-debug --- gradle/publish.gradle | 3 --- kotlinx-coroutines-debug/build.gradle.kts | 25 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/gradle/publish.gradle b/gradle/publish.gradle index d6bee65210..9984ae8e70 100644 --- a/gradle/publish.gradle +++ b/gradle/publish.gradle @@ -13,9 +13,6 @@ def isMultiplatform = project.name == "kotlinx-coroutines-core" || project.name def isBom = project.name == "kotlinx-coroutines-bom" if (!isBom) { - if (project.name == "kotlinx-coroutines-debug") { - apply plugin: "com.github.johnrengelman.shadow" - } // empty xxx-javadoc.jar task javadocJar(type: Jar) { archiveClassifier = 'javadoc' diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index d95e5f7caa..e70c9be9de 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -3,6 +3,8 @@ */ import com.github.jengelman.gradle.plugins.shadow.tasks.* +import java.net.* +import java.nio.file.* plugins { id("com.github.johnrengelman.shadow") @@ -66,6 +68,9 @@ val shadowJar by tasks.getting(ShadowJar::class) { } // // exclude the module-info.class provided by bytebuddy // exclude("META-INF/versions/9/module-info.class") + /* These classifiers are both set to `null` to trick Gradle into thinking that this jar file is both the + artifact from the `jar` task and the one from `shadowJar`. Without this, Gradle complains that the artifact + from the `jar` task is not present when the compilaton finishes, even if the file with this name exists. */ archiveClassifier.convention(null as String?) archiveClassifier.set(null as String?) archiveBaseName.set(jar.archiveBaseName) @@ -78,12 +83,22 @@ val shadowJar by tasks.getting(ShadowJar::class) { )) } VersionFile.fromVersionFile(this, versionFileTask) - from(tasks.compileModuleInfoJava) { - // Include **only** file we are interested in as JavaCompile output also contains some tmp files - include("module-info.class") - into("META-INF/versions/9/") - } duplicatesStrategy = DuplicatesStrategy.FAIL + dependsOn(tasks.compileModuleInfoJava) + doLast { + // add module-info.class to the META-INF/versions/9/ directory. + // We can't do that directly with the shadowJar task because it doesn't support replacing existing files. + val zipPath = this@getting.outputs.files.singleFile.toPath() + val zipUri = URI.create("jar:${zipPath.toUri()}") + println(tasks.compileModuleInfoJava.get().outputs.files.asFileTree.toList()) + val moduleInfoFilePath = tasks.compileModuleInfoJava.get().outputs.files.asFileTree.matching { + include("module-info.class") + }.singleFile.toPath() + FileSystems.newFileSystem(zipUri, emptyMap()).use { fs -> + val moduleInfoFile = fs.getPath("META-INF/versions/9/module-info.class") + Files.copy(moduleInfoFilePath, moduleInfoFile, StandardCopyOption.REPLACE_EXISTING) + } + } } configurations { From 58405ed71190a74eeebf704c20e4b922f2603a23 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Tue, 28 Nov 2023 13:15:29 +0100 Subject: [PATCH 15/18] More configuration avoidance --- kotlinx-coroutines-debug/build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index e70c9be9de..62b2162749 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -54,13 +54,13 @@ tasks.withType().configureEach { } } -val jar by tasks.getting(Jar::class) { +val jar by tasks.existing(Jar::class) { enabled = false } val versionFileTask = VersionFile.registerVersionFileTask(project) -val shadowJar by tasks.getting(ShadowJar::class) { +val shadowJar by tasks.existing(ShadowJar::class) { // Shadow only byte buddy, do not package kotlin stdlib configurations = listOf(project.configurations["shadowDeps"]) relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") { @@ -73,8 +73,8 @@ val shadowJar by tasks.getting(ShadowJar::class) { from the `jar` task is not present when the compilaton finishes, even if the file with this name exists. */ archiveClassifier.convention(null as String?) archiveClassifier.set(null as String?) - archiveBaseName.set(jar.archiveBaseName) - archiveVersion.set(jar.archiveVersion) + archiveBaseName.set(jar.flatMap { it.archiveBaseName }) + archiveVersion.set(jar.flatMap { it.archiveVersion }) manifest { attributes(mapOf( "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain", @@ -88,7 +88,7 @@ val shadowJar by tasks.getting(ShadowJar::class) { doLast { // add module-info.class to the META-INF/versions/9/ directory. // We can't do that directly with the shadowJar task because it doesn't support replacing existing files. - val zipPath = this@getting.outputs.files.singleFile.toPath() + val zipPath = this@existing.outputs.files.singleFile.toPath() val zipUri = URI.create("jar:${zipPath.toUri()}") println(tasks.compileModuleInfoJava.get().outputs.files.asFileTree.toList()) val moduleInfoFilePath = tasks.compileModuleInfoJava.get().outputs.files.asFileTree.matching { From ecf13cd1a00f2070b530554cd9a912355d4e5a05 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Tue, 28 Nov 2023 13:23:08 +0100 Subject: [PATCH 16/18] Fixup --- kotlinx-coroutines-debug/build.gradle.kts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index 62b2162749..a0b0e726e8 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -63,9 +63,7 @@ val versionFileTask = VersionFile.registerVersionFileTask(project) val shadowJar by tasks.existing(ShadowJar::class) { // Shadow only byte buddy, do not package kotlin stdlib configurations = listOf(project.configurations["shadowDeps"]) - relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") { - this.exclude("META-INF/versions/9/module-info.class") - } + relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") // // exclude the module-info.class provided by bytebuddy // exclude("META-INF/versions/9/module-info.class") /* These classifiers are both set to `null` to trick Gradle into thinking that this jar file is both the From a3c9ff889d07769071747bf343f4b5bec46c44a5 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Tue, 28 Nov 2023 16:16:46 +0100 Subject: [PATCH 17/18] Cleanup --- kotlinx-coroutines-debug/build.gradle.kts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index a0b0e726e8..efd6ebe43b 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -12,13 +12,13 @@ plugins { } configurations{ - val shadowDeps by creating - compileOnly.configure { - extendsFrom(shadowDeps) - } - runtimeOnly.configure { - extendsFrom(shadowDeps) - } + val shadowDeps by creating + compileOnly.configure { + extendsFrom(shadowDeps) + } + runtimeOnly.configure { + extendsFrom(shadowDeps) + } } val junit_version by properties @@ -64,8 +64,6 @@ val shadowJar by tasks.existing(ShadowJar::class) { // Shadow only byte buddy, do not package kotlin stdlib configurations = listOf(project.configurations["shadowDeps"]) relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy") - // // exclude the module-info.class provided by bytebuddy - // exclude("META-INF/versions/9/module-info.class") /* These classifiers are both set to `null` to trick Gradle into thinking that this jar file is both the artifact from the `jar` task and the one from `shadowJar`. Without this, Gradle complains that the artifact from the `jar` task is not present when the compilaton finishes, even if the file with this name exists. */ @@ -88,7 +86,6 @@ val shadowJar by tasks.existing(ShadowJar::class) { // We can't do that directly with the shadowJar task because it doesn't support replacing existing files. val zipPath = this@existing.outputs.files.singleFile.toPath() val zipUri = URI.create("jar:${zipPath.toUri()}") - println(tasks.compileModuleInfoJava.get().outputs.files.asFileTree.toList()) val moduleInfoFilePath = tasks.compileModuleInfoJava.get().outputs.files.asFileTree.matching { include("module-info.class") }.singleFile.toPath() @@ -100,7 +97,8 @@ val shadowJar by tasks.existing(ShadowJar::class) { } configurations { - // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but it's not enough. + // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but it's not enough: + // the BOM plugin does not notice it. See artifacts { add("apiElements", shadowJar) add("runtimeElements", shadowJar) From afa50d0e48eedc222c9b99902df9be3777bbfca6 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 29 Nov 2023 11:58:58 +0100 Subject: [PATCH 18/18] Final touches --- .../version-file-conventions.gradle.kts | 22 +++++++-------- kotlinx-coroutines-debug/build.gradle.kts | 28 +++++++++---------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts index fc38eef712..587e184b30 100644 --- a/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/version-file-conventions.gradle.kts @@ -1,17 +1,17 @@ import org.gradle.api.tasks.bundling.* -/* `kotlinx-coroutines-debug` configures `VersionFile` on its own when the corresponding task is created. */ -val invalidModules = listOf("kotlinx-coroutines-debug") - -configure(subprojects.filter { - !unpublished.contains(it.name) && !invalidModules.contains(it.name) && it.name !in sourceless -}) { +configure(subprojects.filter { !unpublished.contains(it.name) && it.name !in sourceless }) { val project = this - val jarTaskName = if (isMultiplatform) "jvmJar" else "jar" - val versionFileTask = VersionFile.registerVersionFileTask(project) - tasks.withType(Jar::class.java).configureEach { - if (name == jarTaskName) { - VersionFile.fromVersionFile(this, versionFileTask) + val jarTaskName = when { + project.name == "kotlinx-coroutines-debug" -> { + project.apply(plugin = "com.github.johnrengelman.shadow") + "shadowJar" } + isMultiplatform -> "jvmJar" + else -> "jar" + } + val versionFileTask = VersionFile.registerVersionFileTask(project) + tasks.withType(Jar::class.java).named(jarTaskName) { + VersionFile.fromVersionFile(this, versionFileTask) } } diff --git a/kotlinx-coroutines-debug/build.gradle.kts b/kotlinx-coroutines-debug/build.gradle.kts index efd6ebe43b..ed8b918b8a 100644 --- a/kotlinx-coroutines-debug/build.gradle.kts +++ b/kotlinx-coroutines-debug/build.gradle.kts @@ -7,11 +7,11 @@ import java.net.* import java.nio.file.* plugins { - id("com.github.johnrengelman.shadow") - id("org.jetbrains.kotlinx.kover") // apply plugin to use autocomplete for Kover DSL + id("com.github.johnrengelman.shadow") + id("org.jetbrains.kotlinx.kover") // apply plugin to use autocomplete for Kover DSL } -configurations{ +configurations { val shadowDeps by creating compileOnly.configure { extendsFrom(shadowDeps) @@ -58,8 +58,6 @@ val jar by tasks.existing(Jar::class) { enabled = false } -val versionFileTask = VersionFile.registerVersionFileTask(project) - val shadowJar by tasks.existing(ShadowJar::class) { // Shadow only byte buddy, do not package kotlin stdlib configurations = listOf(project.configurations["shadowDeps"]) @@ -72,17 +70,17 @@ val shadowJar by tasks.existing(ShadowJar::class) { archiveBaseName.set(jar.flatMap { it.archiveBaseName }) archiveVersion.set(jar.flatMap { it.archiveVersion }) manifest { - attributes(mapOf( - "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain", - "Can-Redefine-Classes" to "true", - "Multi-Release" to "true" - )) + attributes( + mapOf( + "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain", + "Can-Redefine-Classes" to "true", + "Multi-Release" to "true" + ) + ) } - VersionFile.fromVersionFile(this, versionFileTask) - duplicatesStrategy = DuplicatesStrategy.FAIL + // add module-info.class to the META-INF/versions/9/ directory. dependsOn(tasks.compileModuleInfoJava) doLast { - // add module-info.class to the META-INF/versions/9/ directory. // We can't do that directly with the shadowJar task because it doesn't support replacing existing files. val zipPath = this@existing.outputs.files.singleFile.toPath() val zipUri = URI.create("jar:${zipPath.toUri()}") @@ -97,8 +95,8 @@ val shadowJar by tasks.existing(ShadowJar::class) { } configurations { - // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but it's not enough: - // the BOM plugin does not notice it. See + // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but the other subprojects + // that depend on `kotlinx-coroutines-debug` look at `runtimeElements` and `apiElements`. artifacts { add("apiElements", shadowJar) add("runtimeElements", shadowJar)