Skip to content

Commit 3ceb35d

Browse files
authored
Fix kotlinx-coroutines-debug having the wrong module-info (#3948)
Also, rewrite some build logic to gradle.kts
1 parent 5cd845b commit 3ceb35d

File tree

6 files changed

+160
-113
lines changed

6 files changed

+160
-113
lines changed

build.gradle

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != core
177177

178178
apply plugin: "bom-conventions"
179179
apply plugin: "java-modularity-conventions"
180+
apply plugin: "version-file-conventions"
180181

181182
if (build_snapshot_train) {
182183
println "Hacking test tasks, removing stress and flaky tests"
@@ -252,40 +253,6 @@ configure(subprojects.findAll { !unpublished.contains(it.name) }) {
252253
}
253254
}
254255
}
255-
256-
def thisProject = it
257-
if (thisProject.name in sourceless) {
258-
return
259-
}
260-
261-
def versionFileTask = thisProject.tasks.register("versionFileTask") {
262-
def name = thisProject.name.replace("-", "_")
263-
def versionFile = thisProject.layout.buildDirectory.file("${name}.version")
264-
it.outputs.file(versionFile)
265-
266-
it.doLast {
267-
versionFile.get().asFile.text = version.toString()
268-
}
269-
}
270-
271-
List<String> jarTasks
272-
if (isMultiplatform(it)) {
273-
jarTasks = ["jvmJar"]
274-
} else if (it.name == "kotlinx-coroutines-debug") {
275-
// We shadow debug module instead of just packaging it
276-
jarTasks = ["shadowJar"]
277-
} else {
278-
jarTasks = ["jar"]
279-
}
280-
281-
for (name in jarTasks) {
282-
thisProject.tasks.named(name, Jar) {
283-
it.dependsOn versionFileTask
284-
it.from(versionFileTask) {
285-
into("META-INF")
286-
}
287-
}
288-
}
289256
}
290257

291258
// Report Kotlin compiler version when building project
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
import org.gradle.api.*
6+
import org.gradle.api.tasks.*
7+
8+
/**
9+
* Adds 'module_name.version' file to the project's JAR META-INF
10+
* for the better toolability. See #2941
11+
*/
12+
object VersionFile {
13+
fun registerVersionFileTask(project: Project): TaskProvider<Task> {
14+
val versionFile = project.layout.buildDirectory.file("${project.name.replace('-', '_')}.version")
15+
val version = project.version.toString()
16+
return project.tasks.register("versionFileTask") {
17+
outputs.file(versionFile)
18+
doLast {
19+
versionFile.get().asFile.writeText(version)
20+
}
21+
}
22+
}
23+
24+
fun fromVersionFile(target: AbstractCopyTask, versionFileTask: TaskProvider<Task>) {
25+
target.from(versionFileTask) {
26+
into("META-INF")
27+
}
28+
}
29+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import org.gradle.api.tasks.bundling.*
2+
3+
configure(subprojects.filter { !unpublished.contains(it.name) && it.name !in sourceless }) {
4+
val project = this
5+
val jarTaskName = when {
6+
project.name == "kotlinx-coroutines-debug" -> {
7+
project.apply(plugin = "com.github.johnrengelman.shadow")
8+
"shadowJar"
9+
}
10+
isMultiplatform -> "jvmJar"
11+
else -> "jar"
12+
}
13+
val versionFileTask = VersionFile.registerVersionFileTask(project)
14+
tasks.withType(Jar::class.java).named(jarTaskName) {
15+
VersionFile.fromVersionFile(this, versionFileTask)
16+
}
17+
}

gradle/publish.gradle

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
import org.gradle.util.VersionNumber
6-
75
// Configures publishing of Maven artifacts to Maven Central
86

97
apply plugin: 'maven-publish'
@@ -15,10 +13,6 @@ def isMultiplatform = project.name == "kotlinx-coroutines-core" || project.name
1513
def isBom = project.name == "kotlinx-coroutines-bom"
1614

1715
if (!isBom) {
18-
if (project.name == "kotlinx-coroutines-debug") {
19-
apply plugin: "com.github.johnrengelman.shadow"
20-
}
21-
2216
// empty xxx-javadoc.jar
2317
task javadocJar(type: Jar) {
2418
archiveClassifier = 'javadoc'

kotlinx-coroutines-debug/build.gradle

Lines changed: 0 additions & 73 deletions
This file was deleted.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
import com.github.jengelman.gradle.plugins.shadow.tasks.*
6+
import java.net.*
7+
import java.nio.file.*
8+
9+
plugins {
10+
id("com.github.johnrengelman.shadow")
11+
id("org.jetbrains.kotlinx.kover") // apply plugin to use autocomplete for Kover DSL
12+
}
13+
14+
configurations {
15+
val shadowDeps by creating
16+
compileOnly.configure {
17+
extendsFrom(shadowDeps)
18+
}
19+
runtimeOnly.configure {
20+
extendsFrom(shadowDeps)
21+
}
22+
}
23+
24+
val junit_version by properties
25+
val junit5_version by properties
26+
val byte_buddy_version by properties
27+
val blockhound_version by properties
28+
val jna_version by properties
29+
30+
dependencies {
31+
compileOnly("junit:junit:$junit_version")
32+
compileOnly("org.junit.jupiter:junit-jupiter-api:$junit5_version")
33+
testImplementation("org.junit.jupiter:junit-jupiter-engine:$junit5_version")
34+
testImplementation("org.junit.platform:junit-platform-testkit:1.7.0")
35+
add("shadowDeps", "net.bytebuddy:byte-buddy:$byte_buddy_version")
36+
add("shadowDeps", "net.bytebuddy:byte-buddy-agent:$byte_buddy_version")
37+
compileOnly("io.projectreactor.tools:blockhound:$blockhound_version")
38+
testImplementation("io.projectreactor.tools:blockhound:$blockhound_version")
39+
testImplementation("com.google.code.gson:gson:2.8.6")
40+
api("net.java.dev.jna:jna:$jna_version")
41+
api("net.java.dev.jna:jna-platform:$jna_version")
42+
}
43+
44+
java {
45+
/* This is needed to be able to run JUnit5 tests. Otherwise, Gradle complains that it can't find the
46+
JVM1.6-compatible version of the `junit-jupiter-api` artifact. */
47+
disableAutoTargetJvm()
48+
}
49+
50+
// This is required for BlockHound tests to work, see https://github.com/Kotlin/kotlinx.coroutines/issues/3701
51+
tasks.withType<Test>().configureEach {
52+
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) {
53+
jvmArgs("-XX:+AllowRedefinitionToAddDeleteMethods")
54+
}
55+
}
56+
57+
val jar by tasks.existing(Jar::class) {
58+
enabled = false
59+
}
60+
61+
val shadowJar by tasks.existing(ShadowJar::class) {
62+
// Shadow only byte buddy, do not package kotlin stdlib
63+
configurations = listOf(project.configurations["shadowDeps"])
64+
relocate("net.bytebuddy", "kotlinx.coroutines.repackaged.net.bytebuddy")
65+
/* These classifiers are both set to `null` to trick Gradle into thinking that this jar file is both the
66+
artifact from the `jar` task and the one from `shadowJar`. Without this, Gradle complains that the artifact
67+
from the `jar` task is not present when the compilaton finishes, even if the file with this name exists. */
68+
archiveClassifier.convention(null as String?)
69+
archiveClassifier.set(null as String?)
70+
archiveBaseName.set(jar.flatMap { it.archiveBaseName })
71+
archiveVersion.set(jar.flatMap { it.archiveVersion })
72+
manifest {
73+
attributes(
74+
mapOf(
75+
"Premain-Class" to "kotlinx.coroutines.debug.AgentPremain",
76+
"Can-Redefine-Classes" to "true",
77+
"Multi-Release" to "true"
78+
)
79+
)
80+
}
81+
// add module-info.class to the META-INF/versions/9/ directory.
82+
dependsOn(tasks.compileModuleInfoJava)
83+
doLast {
84+
// We can't do that directly with the shadowJar task because it doesn't support replacing existing files.
85+
val zipPath = this@existing.outputs.files.singleFile.toPath()
86+
val zipUri = URI.create("jar:${zipPath.toUri()}")
87+
val moduleInfoFilePath = tasks.compileModuleInfoJava.get().outputs.files.asFileTree.matching {
88+
include("module-info.class")
89+
}.singleFile.toPath()
90+
FileSystems.newFileSystem(zipUri, emptyMap<String, String>()).use { fs ->
91+
val moduleInfoFile = fs.getPath("META-INF/versions/9/module-info.class")
92+
Files.copy(moduleInfoFilePath, moduleInfoFile, StandardCopyOption.REPLACE_EXISTING)
93+
}
94+
}
95+
}
96+
97+
configurations {
98+
// shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but the other subprojects
99+
// that depend on `kotlinx-coroutines-debug` look at `runtimeElements` and `apiElements`.
100+
artifacts {
101+
add("apiElements", shadowJar)
102+
add("runtimeElements", shadowJar)
103+
}
104+
}
105+
106+
koverReport {
107+
filters {
108+
excludes {
109+
// Never used, safety mechanism
110+
classes("kotlinx.coroutines.debug.internal.NoOpProbesKt")
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)