[Gradle] Add property to disable Kotlin compiler daemon fallback strategy

#KT-48843 Fixed
This commit is contained in:
Alexander Likhachev
2022-08-05 02:36:28 +02:00
parent 41e6f7efc5
commit 5fa7fcb7a8
10 changed files with 62 additions and 21 deletions
@@ -64,4 +64,12 @@ interface CompileUsingKotlinDaemon : Task {
*/
@get:Internal
val compilerExecutionStrategy: Property<KotlinCompilerExecutionStrategy>
/**
* 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<Boolean>
}
@@ -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<String>?,
val strategy: KotlinCompilerExecutionStrategy,
val useDaemonFallbackStrategy: Boolean,
) : Serializable {
companion object {
const val serialVersionUID: Long = 0
}
}
@@ -30,11 +30,10 @@ import javax.inject.Inject
internal class GradleCompilerRunnerWithWorkers(
taskProvider: GradleCompileTaskProvider,
jdkToolsJar: File?,
kotlinDaemonJvmArgs: List<String>?,
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?
@@ -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<String>?,
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(
@@ -63,11 +63,10 @@ internal class GradleKotlinCompilerWorkArguments(
val reportingSettings: ReportingSettings,
val kotlinScriptExtensions: Array<String>,
val allWarningsAsErrors: Boolean,
val daemonJvmArgs: List<String>?,
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<String> = 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
@@ -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(),
@@ -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) {
@@ -342,9 +342,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
GradleCompilerRunnerWithWorkers(
taskProvider,
toolsJar,
normalizedKotlinDaemonJvmArguments.orNull,
CompilerExecutionSettings(
normalizedKotlinDaemonJvmArguments.orNull,
params.second,
useDaemonFallbackStrategy.get()
),
params.first,
params.second,
workerExecutor
)
}
@@ -67,7 +67,8 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
kotlinDaemonJvmArgs.split("\\s+".toRegex())
})
}
task.compilerExecutionStrategy.value(propertiesProvider.kotlinCompilerExecutionStrategy)
task.compilerExecutionStrategy.convention(propertiesProvider.kotlinCompilerExecutionStrategy).finalizeValueOnRead()
task.useDaemonFallbackStrategy.convention(propertiesProvider.kotlinDaemonUseFallbackStrategy).finalizeValueOnRead()
task.incremental = false
task.useModuleDetection.convention(false)
@@ -251,7 +251,8 @@ internal class KaptWithKotlincConfig(kotlinCompileTask: KotlinCompile, ext: Kapt
propertiesProvider.kotlinDaemonJvmArgs?.let {
task.kotlinDaemonJvmArguments.value(it.split("\\s+".toRegex())).disallowChanges()
}
task.compilerExecutionStrategy.value(propertiesProvider.kotlinCompilerExecutionStrategy).disallowChanges()
task.compilerExecutionStrategy.convention(propertiesProvider.kotlinCompilerExecutionStrategy).finalizeValueOnRead()
task.useDaemonFallbackStrategy.convention(propertiesProvider.kotlinDaemonUseFallbackStrategy).finalizeValueOnRead()
}
}
}