Skip to content

Commit f69011c

Browse files
timofey-soloninSpace Team
authored andcommitted
Workaround coroutines hang due to Gradle dependencies downgrading stdlib
Since 2.2.20 uncaught exceptions in coroutines make the -ea executions hang if the stdlib is downgraded without appropriate -api-version downgrade. In KGP-IT Test process we don't want stdlib downgrade, so this change filters out the downgraded stdlib. In other Gradle-related tests we can just disable coroutines stacktrace recovery if embedded stdlib is present. ^KT-79528
1 parent 68ec2b1 commit f69011c

File tree

6 files changed

+82
-1
lines changed

6 files changed

+82
-1
lines changed

libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,5 @@ tasks.withType<Test>().configureEach {
528528
})
529529
}
530530
}
531+
532+
excludeGradleEmbeddedStdlibFromTestTasksRuntimeClasspath()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.jetbrains.kotlin.gradle
2+
3+
import kotlin.test.Test
4+
import kotlinx.coroutines.async
5+
import kotlinx.coroutines.runBlocking
6+
import org.jetbrains.kotlin.util.assertThrows
7+
8+
class KT79528StdlibDowngradeHangs {
9+
10+
@Test
11+
fun `test KT-79528 - test Gradle doesn't downgrade stdlib and cause uncaught exceptions in coroutines to hang coroutines machinery`() {
12+
class Foo : RuntimeException()
13+
assertThrows<Foo> {
14+
runBlocking {
15+
async {
16+
throw Foo()
17+
}.await()
18+
}
19+
}
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.jetbrains.kotlin.gradle.unitTests
2+
3+
import kotlin.test.Test
4+
import kotlinx.coroutines.async
5+
import kotlinx.coroutines.runBlocking
6+
import org.jetbrains.kotlin.util.assertThrows
7+
8+
class KT79528StdlibDowngradeHangs {
9+
10+
@Test
11+
fun `test KT-79528 - test Gradle doesn't downgrade stdlib and cause uncaught exceptions in coroutines to hang coroutines machinery`() {
12+
class Foo : RuntimeException()
13+
assertThrows<Foo> {
14+
runBlocking {
15+
async {
16+
throw Foo()
17+
}.await()
18+
}
19+
}
20+
}
21+
}

repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/GradleCommon.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import org.gradle.api.Action
1010
import org.gradle.api.GradleException
1111
import org.gradle.api.Project
1212
import org.gradle.api.artifacts.Configuration
13+
import org.gradle.api.artifacts.FileCollectionDependency
1314
import org.gradle.api.artifacts.ModuleDependency
1415
import org.gradle.api.artifacts.VersionCatalogsExtension
1516
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
@@ -31,6 +32,7 @@ import org.gradle.api.tasks.Copy
3132
import org.gradle.api.tasks.SourceSet
3233
import org.gradle.api.tasks.TaskProvider
3334
import org.gradle.api.tasks.compile.JavaCompile
35+
import org.gradle.api.tasks.testing.Test
3436
import org.gradle.jvm.tasks.Jar
3537
import org.gradle.jvm.toolchain.JavaToolchainService
3638
import org.gradle.kotlin.dsl.*
@@ -39,6 +41,7 @@ import org.gradle.plugin.devel.PluginDeclaration
3941
import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
4042
import org.gradle.plugin.devel.tasks.ValidatePlugins
4143
import org.gradle.plugin.use.resolve.internal.ArtifactRepositoriesPluginResolver.PLUGIN_MARKER_SUFFIX
44+
import org.gradle.process.CommandLineArgumentProvider
4245
import org.gradle.util.GradleVersion
4346
import org.jetbrains.kotlin.buildtools.api.ExperimentalBuildToolsApi
4447
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
@@ -51,6 +54,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
5154
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
5255
import plugins.configureDefaultPublishing
5356
import plugins.configureKotlinPomAttributes
57+
import java.io.File
5458

5559
/**
5660
* We have to handle the returned provider lazily, because the publication's artifactId
@@ -808,4 +812,33 @@ fun Project.registerKotlinSourceForVersionRange(
808812
}
809813
}
810814
}
811-
}
815+
}
816+
817+
// See KT-79528 and https://github.com/gradle/gradle/issues/34453
818+
fun Project.disableCoroutinesStacktraceRecoveryInTestsIfGradleEmbeddedStdlibIsInRuntimeClasspath() {
819+
tasks.withType<Test>().configureEach {
820+
val isEmbeddedStdlibInRuntimeClasspath = provider {
821+
classpath.contains(gradleEmbeddedStdlib())
822+
}
823+
jvmArgumentProviders.add {
824+
if (isEmbeddedStdlibInRuntimeClasspath.get()) {
825+
listOf("-Dkotlinx.coroutines.stacktrace.recovery=false")
826+
} else {
827+
emptyList()
828+
}
829+
}
830+
}
831+
}
832+
833+
fun Project.excludeGradleEmbeddedStdlibFromTestTasksRuntimeClasspath() {
834+
afterEvaluate {
835+
tasks.withType<Test>().configureEach {
836+
val embeddedStdlib = gradleEmbeddedStdlib()
837+
classpath = classpath.filter {
838+
it != embeddedStdlib
839+
}
840+
}
841+
}
842+
}
843+
844+
private fun Project.gradleEmbeddedStdlib(): File = (dependencies.gradleApi() as FileCollectionDependency).files.single { it.name.startsWith("kotlin-stdlib") }

repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/gradle-plugin-common-configuration.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,5 @@ if (!kotlinBuildProperties.isInJpsBuildIdeaSync) {
123123
)
124124
publishShadowedJar(gradle813SourceSet, commonSourceSet)
125125
}
126+
127+
disableCoroutinesStacktraceRecoveryInTestsIfGradleEmbeddedStdlibIsInRuntimeClasspath()

repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/gradle-plugin-dependency-configuration.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ publishing {
8686
}
8787
}
8888

89+
disableCoroutinesStacktraceRecoveryInTestsIfGradleEmbeddedStdlibIsInRuntimeClasspath()

0 commit comments

Comments
 (0)