【问题标题】:Compiling android project with kotlin on TeamCity fails在 TeamCity 上使用 kotlin 编译 android 项目失败
【发布时间】:2020-10-07 22:48:27
【问题描述】:

我的构建步骤使用来自 TeamCity 的 gradle build in 模板,但不幸的是我得到了:

[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)

关于我为什么会得到这个的任何想法?

【问题讨论】:

  • 请显示您的 build.gradle 文件
  • 哇,这太酷了。对此发表评论两天后,我遇到了同样的问题...查看我的解决方案的答案

标签: android continuous-integration kotlin teamcity travis-ci


【解决方案1】:

默认情况下,Kotlin 编译器在其自己的进程守护进程中执行。在 CI 上运行时将此配置传递给 Gradle,以便在同一构建过程中编译 Kotlin:

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

禁用 Gradle 守护程序也是 CI 环境中的常见做法:

-Dorg.gradle.daemon=false

人们可能认为 Gradle 守护进程属性也会禁用 Kotlin 编译器运行守护进程,但目前情况并非如此。 GradleKotlinCompilerWork.kt 只考虑org.gradle.daemon 属性之后 kotlin.compiler.execution.strategy 属性。如果没有定义执行策略,则runner默认使用"daemon"策略:

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)
}

无论 Gradle 守护程序配置如何,将执行策略显式设置为 "in-process" 都会让您到达 compileInProcess(),但是,您可能需要在 CI 服务器上禁用这两个守护程序。

【讨论】:

【解决方案2】:

我遇到了同样的问题。不过,它并没有连接到 Kotlin。

我不得不禁用 gradle 守护程序(无论如何不建议在 CI 服务器上使用它)。

在 teamcity 中,您可以例如通过将-Dorg.gradle.daemon=false 添加到GRADLE_OPTS 环境变量来实现。

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

【讨论】:

  • 这是正确的。同样从 Gradle 3.0 开始,Gradle 默认是守护进程,这意味着 KotlinCompileDaemon 将继续存在。
  • 链接中的注释:从 Gradle 3.0 开始,我们默认启用 Daemon,建议在开发人员的机器和持续集成服务器上都使用它。但是,如果您怀疑 Daemon 使您的 CI 构建不稳定,您可以禁用它,以便为每个构建使用新的运行时,因为运行时与任何以前的构建完全隔离。
  • @lovis 环境变量会覆盖 gradle.properties 值吗?我们想在开发环境中启用守护进程,但在 CI 服务器上禁用它。
  • @RyanR afaik gradle.properties 战胜了环境变量,但我不是 100% 确定(而且绝对不是专家)。对不起:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
相关资源
最近更新 更多