Improve log messages when failing to compile with daemon
Instead of letting `compileWithDaemon` return null, allow it to throw exceptions so that the caller can catch those exceptions and log clearer messages on why it failed. ^KT-31602 In progress
This commit is contained in:
+30
-43
@@ -18,10 +18,10 @@ import org.jetbrains.kotlin.gradle.report.*
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
|
||||||
import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState
|
import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState
|
||||||
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
|
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
|
||||||
import org.jetbrains.kotlin.gradle.utils.stackTraceAsString
|
|
||||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||||
import org.jetbrains.kotlin.incremental.ClasspathChanges
|
import org.jetbrains.kotlin.incremental.ClasspathChanges
|
||||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||||
|
import org.jetbrains.kotlin.util.suffixIfNot
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
@@ -147,12 +147,14 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (compilerExecutionStrategy == KotlinCompilerExecutionStrategy.DAEMON) {
|
if (compilerExecutionStrategy == KotlinCompilerExecutionStrategy.DAEMON) {
|
||||||
val daemonExitCode = compileWithDaemon(messageCollector)
|
try {
|
||||||
|
return compileWithDaemon(messageCollector) to KotlinCompilerExecutionStrategy.DAEMON
|
||||||
if (daemonExitCode != null) {
|
} catch (e: Throwable) {
|
||||||
return daemonExitCode to KotlinCompilerExecutionStrategy.DAEMON
|
log.warn(
|
||||||
} else {
|
"Failed to compile with Kotlin daemon: ${e.stackTraceToString().suffixIfNot("\n")}" +
|
||||||
log.warn("Could not connect to kotlin daemon. Using fallback strategy.")
|
"Using fallback strategy: Compile without Kotlin daemon\n" +
|
||||||
|
"Try ./gradlew --stop if this issue persists."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,35 +166,21 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? {
|
private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode {
|
||||||
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
|
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
|
||||||
val daemonMessageCollector =
|
val daemonMessageCollector =
|
||||||
if (isDebugEnabled) messageCollector else MessageCollector.NONE
|
if (isDebugEnabled) messageCollector else MessageCollector.NONE
|
||||||
val connection =
|
val connection =
|
||||||
metrics.measure(BuildTime.CONNECT_TO_DAEMON) {
|
metrics.measure(BuildTime.CONNECT_TO_DAEMON) {
|
||||||
try {
|
GradleCompilerRunner.getDaemonConnectionImpl(
|
||||||
GradleCompilerRunner.getDaemonConnectionImpl(
|
clientIsAliveFlagFile,
|
||||||
clientIsAliveFlagFile,
|
sessionFlagFile,
|
||||||
sessionFlagFile,
|
compilerFullClasspath,
|
||||||
compilerFullClasspath,
|
daemonMessageCollector,
|
||||||
daemonMessageCollector,
|
isDebugEnabled = isDebugEnabled,
|
||||||
isDebugEnabled = isDebugEnabled,
|
daemonJvmArgs = daemonJvmArgs
|
||||||
daemonJvmArgs = daemonJvmArgs
|
)
|
||||||
)
|
} ?: throw RuntimeException(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE) // TODO: Add root cause
|
||||||
} catch (e: Throwable) {
|
|
||||||
log.error("Caught an exception trying to connect to Kotlin Daemon:")
|
|
||||||
log.error(e.stackTraceAsString())
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (connection == null) {
|
|
||||||
if (isIncremental) {
|
|
||||||
log.warn("Could not perform incremental compilation: $COULD_NOT_CONNECT_TO_DAEMON_MESSAGE")
|
|
||||||
} else {
|
|
||||||
log.warn(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val (daemon, sessionId) = connection
|
val (daemon, sessionId) = connection
|
||||||
|
|
||||||
@@ -218,19 +206,18 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
|||||||
exitCodeFromProcessExitCode(log, res.get())
|
exitCodeFromProcessExitCode(log, res.get())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
bufferingMessageCollector.flush(messageCollector)
|
bufferingMessageCollector.flush(messageCollector)
|
||||||
log.error("Compilation with Kotlin compile daemon was not successful")
|
throw e
|
||||||
log.error(e.stackTraceAsString())
|
} finally {
|
||||||
null
|
// todo: can we clear cache on the end of session?
|
||||||
}
|
// often source of the NoSuchObjectException and UnmarshalException, probably caused by the failed/crashed/exited daemon
|
||||||
// todo: can we clear cache on the end of session?
|
// TODO: implement a proper logic to avoid remote calls in such cases
|
||||||
// often source of the NoSuchObjectException and UnmarshalException, probably caused by the failed/crashed/exited daemon
|
try {
|
||||||
// TODO: implement a proper logic to avoid remote calls in such cases
|
metrics.measure(BuildTime.CLEAR_JAR_CACHE) {
|
||||||
try {
|
daemon.clearJarCache()
|
||||||
metrics.measure(BuildTime.CLEAR_JAR_CACHE) {
|
}
|
||||||
daemon.clearJarCache()
|
} catch (e: RemoteException) {
|
||||||
|
log.warn("Unable to clear jar cache after compilation, maybe daemon is already down: $e")
|
||||||
}
|
}
|
||||||
} catch (e: RemoteException) {
|
|
||||||
log.warn("Unable to clear jar cache after compilation, maybe daemon is already down: $e")
|
|
||||||
}
|
}
|
||||||
log.logFinish(KotlinCompilerExecutionStrategy.DAEMON)
|
log.logFinish(KotlinCompilerExecutionStrategy.DAEMON)
|
||||||
return exitCode
|
return exitCode
|
||||||
|
|||||||
Reference in New Issue
Block a user