From 5fa7fcb7a8096fd9cae058436220dc7f20173efc Mon Sep 17 00:00:00 2001 From: Alexander Likhachev Date: Fri, 5 Aug 2022 02:36:28 +0200 Subject: [PATCH] [Gradle] Add property to disable Kotlin compiler daemon fallback strategy #KT-48843 Fixed --- .../gradle/tasks/CompileUsingKotlinDaemon.kt | 8 +++++++ .../CompilerExecutionSettings.kt | 19 +++++++++++++++++ .../GradleCompilerRunnerWithWorkers.kt | 5 ++--- .../GradleKotlinCompilerRunner.kt | 6 ++---- .../GradleKotlinCompilerWork.kt | 21 ++++++++++++------- .../internal/kapt/KaptWithKotlincTask.kt | 8 +++++-- .../kotlin/gradle/plugin/KotlinProperties.kt | 3 +++ .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 7 +++++-- .../AbstractKotlinCompileConfig.kt | 3 ++- .../gradle/tasks/configuration/KaptConfig.kt | 3 ++- 10 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerExecutionSettings.kt diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemon.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemon.kt index e6f1dfc43fc..6e456f1f366 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemon.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/CompileUsingKotlinDaemon.kt @@ -64,4 +64,12 @@ interface CompileUsingKotlinDaemon : Task { */ @get:Internal val compilerExecutionStrategy: Property + + /** + * Defines whether task execution should fail when [compilerExecutionStrategy] is set to [KotlinCompilerExecutionStrategy.DAEMON] + * and compilation via Kotlin daemon was not possible. If set to true then compilation in such case will be retried without the daemon. + * Default is `true` + */ + @get:Internal + val useDaemonFallbackStrategy: Property } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerExecutionSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerExecutionSettings.kt new file mode 100644 index 00000000000..9c980d4c9d6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/CompilerExecutionSettings.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.compilerRunner + +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy +import java.io.Serializable + +internal data class CompilerExecutionSettings( + val daemonJvmArgs: List?, + val strategy: KotlinCompilerExecutionStrategy, + val useDaemonFallbackStrategy: Boolean, +) : Serializable { + companion object { + const val serialVersionUID: Long = 0 + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt index e0e4d86f72b..44b0fd7f779 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt @@ -30,11 +30,10 @@ import javax.inject.Inject internal class GradleCompilerRunnerWithWorkers( taskProvider: GradleCompileTaskProvider, jdkToolsJar: File?, - kotlinDaemonJvmArgs: List?, + compilerExecutionSettings: CompilerExecutionSettings, buildMetrics: BuildMetricsReporter, - compilerExecutionStrategy: KotlinCompilerExecutionStrategy, private val workerExecutor: WorkerExecutor -) : GradleCompilerRunner(taskProvider, jdkToolsJar, kotlinDaemonJvmArgs, buildMetrics, compilerExecutionStrategy) { +) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics) { override fun runCompilerAsync( workArgs: GradleKotlinCompilerWorkArguments, taskOutputsBackup: TaskOutputsBackup? diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 4aaa6770ee7..dd84915a294 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -60,9 +60,8 @@ is not assignable to 'org.gradle.api.tasks.TaskProvider'" exception internal open class GradleCompilerRunner( protected val taskProvider: GradleCompileTaskProvider, protected val jdkToolsJar: File?, - protected val kotlinDaemonJvmArgs: List?, + protected val compilerExecutionSettings: CompilerExecutionSettings, protected val buildMetrics: BuildMetricsReporter, - protected val compilerExecutionStrategy: KotlinCompilerExecutionStrategy, ) { internal val pathProvider = taskProvider.path.get() @@ -211,8 +210,7 @@ internal open class GradleCompilerRunner( reportingSettings = environment.reportingSettings, kotlinScriptExtensions = environment.kotlinScriptExtensions, allWarningsAsErrors = compilerArgs.allWarningsAsErrors, - daemonJvmArgs = kotlinDaemonJvmArgs, - compilerExecutionStrategy = compilerExecutionStrategy, + compilerExecutionSettings = compilerExecutionSettings, ) TaskLoggers.put(pathProvider, loggerProvider) return runCompilerAsync( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index f6aa4af8a71..4c4c9668bab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -63,11 +63,10 @@ internal class GradleKotlinCompilerWorkArguments( val reportingSettings: ReportingSettings, val kotlinScriptExtensions: Array, val allWarningsAsErrors: Boolean, - val daemonJvmArgs: List?, - val compilerExecutionStrategy: KotlinCompilerExecutionStrategy, + val compilerExecutionSettings: CompilerExecutionSettings, ) : Serializable { companion object { - const val serialVersionUID: Long = 0 + const val serialVersionUID: Long = 1 } } @@ -99,8 +98,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( private val buildDir = config.projectFiles.buildDir private val metrics = if (reportingSettings.buildReportOutputs.isNotEmpty()) BuildMetricsReporterImpl() else DoNothingBuildMetricsReporter private var icLogLines: List = emptyList() - private val daemonJvmArgs = config.daemonJvmArgs - private val compilerExecutionStrategy = config.compilerExecutionStrategy + private val compilerExecutionSettings = config.compilerExecutionSettings private val log: KotlinLogger = TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } } @@ -146,10 +144,17 @@ internal class GradleKotlinCompilerWork @Inject constructor( kotlinDebug { "$taskPath Kotlin compiler args: ${compilerArgs.joinToString(" ")}" } } - if (compilerExecutionStrategy == KotlinCompilerExecutionStrategy.DAEMON) { + if (compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.DAEMON) { try { return compileWithDaemon(messageCollector) to KotlinCompilerExecutionStrategy.DAEMON } catch (e: Throwable) { + if (!compilerExecutionSettings.useDaemonFallbackStrategy) { + throw RuntimeException( + "Failed to compile with Kotlin daemon. Fallback strategy (compiling without Kotlin daemon) is turned off. " + + "Try ./gradlew --stop if this issue persists.", + e + ) + } log.warn( "Failed to compile with Kotlin daemon: ${e.stackTraceToString().suffixIfNot("\n")}" + "Using fallback strategy: Compile without Kotlin daemon\n" + @@ -159,7 +164,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( } val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean) - return if (compilerExecutionStrategy == KotlinCompilerExecutionStrategy.IN_PROCESS || isGradleDaemonUsed == false) { + return if (compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.IN_PROCESS || isGradleDaemonUsed == false) { compileInProcess(messageCollector) to KotlinCompilerExecutionStrategy.IN_PROCESS } else { compileOutOfProcess() to KotlinCompilerExecutionStrategy.OUT_OF_PROCESS @@ -178,7 +183,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( compilerFullClasspath, daemonMessageCollector, isDebugEnabled = isDebugEnabled, - daemonJvmArgs = daemonJvmArgs + daemonJvmArgs = compilerExecutionSettings.daemonJvmArgs ) } ?: throw RuntimeException(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE) // TODO: Add root cause diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt index 9257c93e909..fda91e1fd51 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithKotlincTask.kt @@ -13,6 +13,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.work.InputChanges import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.compilerRunner.CompilerExecutionSettings import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl @@ -113,9 +114,12 @@ abstract class KaptWithKotlincTask @Inject constructor( val compilerRunner = GradleCompilerRunner( taskProvider.get(), defaultKotlinJavaToolchain.get().currentJvmJdkToolsJar.orNull, - normalizedKotlinDaemonJvmArguments.orNull, + CompilerExecutionSettings( + normalizedKotlinDaemonJvmArguments.orNull, + compilerExecutionStrategy.get(), + useDaemonFallbackStrategy.get() + ), metrics.get(), - compilerExecutionStrategy.get(), ) compilerRunner.runJvmCompilerAsync( sourcesToCompile = emptyList(), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index 0547f4bef47..0d833687ea9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -429,6 +429,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val kotlinCompilerExecutionStrategy: KotlinCompilerExecutionStrategy get() = KotlinCompilerExecutionStrategy.fromProperty(property("kotlin.compiler.execution.strategy")?.toLowerCase()) + val kotlinDaemonUseFallbackStrategy: Boolean + get() = booleanProperty("kotlin.daemon.useFallbackStrategy") ?: true + private fun propertyWithDeprecatedVariant(propName: String, deprecatedPropName: String): String? { val deprecatedProperty = property(deprecatedPropName) if (deprecatedProperty != null) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index a191134a260..04ec5fe4715 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -342,9 +342,12 @@ abstract class AbstractKotlinCompile @Inject constr GradleCompilerRunnerWithWorkers( taskProvider, toolsJar, - normalizedKotlinDaemonJvmArguments.orNull, + CompilerExecutionSettings( + normalizedKotlinDaemonJvmArguments.orNull, + params.second, + useDaemonFallbackStrategy.get() + ), params.first, - params.second, workerExecutor ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index f8140ae309e..98eb1198ee8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt @@ -67,7 +67,8 @@ internal abstract class AbstractKotlinCompileConfig