Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling android project with kotlin on TeamCity fails

My build step uses the gradle build in template from TeamCity but unfortunately I get:

[16:29:22][:presentation:compileLocalDebugKotlin] Using kotlin incremental compilation
[16:29:48][:presentation:compileLocalDebugKotlin] Compilation with Kotlin compile daemon was not successful
[16:29:48][:presentation:compileLocalDebugKotlin] java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
[16:29:48][:presentation:compileLocalDebugKotlin]   java.io.EOFException
[16:29:48][:presentation:compileLocalDebugKotlin]   at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:229)
[16:29:48][:presentation:compileLocalDebugKotlin]   at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)

Any ideas on why I might get this?

like image 607
Calin Avatar asked Jun 23 '17 13:06

Calin


2 Answers

By default, the Kotlin compiler executes in its own process daemon. Pass this configuration to Gradle when running on CI to compile Kotlin in the same build process:

-Dkotlin.compiler.execution.strategy="in-process"

Disabling the Gradle daemon is also common practice in CI environments:

-Dorg.gradle.daemon=false

One might expect that the Gradle daemon property would also disable the Kotlin compiler runner daemon, but that's not what currently happens. GradleKotlinCompilerWork.kt only considers the org.gradle.daemon property after the kotlin.compiler.execution.strategy property. If the execution strategy is not defined, the runner uses the "daemon" strategy by default:

val executionStrategy = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY
if (executionStrategy == DAEMON_EXECUTION_STRATEGY) {
    val daemonExitCode = compileWithDaemon(compilerClassName, compilerArgs, environment)

    if (daemonExitCode != null) {
        return daemonExitCode
    }
    else {
        log.warn("Could not connect to kotlin daemon. Using fallback strategy.")
    }
}

val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean)
return if (executionStrategy == IN_PROCESS_EXECUTION_STRATEGY || isGradleDaemonUsed == false) {
    compileInProcess(argsArray, compilerClassName, environment)
}
else {
    compileOutOfProcess(argsArray, compilerClassName, environment)
}

Explicitly setting the execution strategy to "in-process" will get you to compileInProcess() regardless of the Gradle daemon configuration, however, you may need to disable both daemons on CI servers.

like image 52
James Wald Avatar answered Sep 27 '22 21:09

James Wald


I ran into the same issue. It was not connected to Kotlin, though.

I had to disable the gradle deamon (it's not recommended on CI servers anyway).

In teamcity you can e.g. do it by adding -Dorg.gradle.daemon=false to the GRADLE_OPTS environment variable.

See https://docs.gradle.org/current/userguide/gradle_daemon.html

like image 40
Lovis Avatar answered Sep 27 '22 21:09

Lovis