Android AGP 8 + Gradle 8 + Kotlin 1.8 导致 Kapt 出错。

14

我刚刚更新到Android Studio Flamingo | 2022.2.1。现在我遇到了这个错误:

Execution failed for task ':app:kaptGenerateStubsDebugKotlin'.
> 'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

我正在使用AS包含的Kotlin,版本为1.8.0,但是在AGP 7.4.2和Gradle 7.5可以正常工作 - 只有在从AS Flamingo更新Gradle和AGP后才会出现问题。此外:

  • 如果我将Kotlin降级到1.7.20,它就能再次正常工作
  • 如果我将Kotlin升级到1.8.20,它就会出现上述错误

我确实有编译选项:

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }

我也尝试了示例AS应用程序,但它们使用的是Kotlin 1.7.20。它们也可以与Kotlin 1.8.0一起使用 - 除非您在依赖项中引入kapt!(例如Dagger)

那么,应该使用哪种组合才能正常工作 - 包括kapt - 并具有Android Studio推荐的最新稳定版本?

  • Android Studio版本?
  • AGP版本?
  • Gradle版本?
  • Kotlin版本?

请不要提供未经测试的答案。我知道它“应该”可以工作,但实际上并不行。


我相信这可能是与此处相同的问题? - JustSightseeing
1
这是不同的问题,与使用错误的JDK进行编译有关。这与预处理器和编译选项有关。 - RumburaK
4个回答

13

最新的Android Gradle插件和Kotlin kapt之间存在兼容性问题。因此,在Android配置中指定的jvmTarget将设置在Kotlin编译任务上,但不会设置在kapt任务上,默认情况下使用工具链版本(当前为JDK 17)。

作为解决方法,手动在kapt任务上设置jvmTarget(在您的情况下,目标是Java 1.8):

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs).configureEach {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

2
你有最新的Android Gradle插件和Kotlin kapt之间相关兼容性问题的链接吗? - chrisfey
1
谢谢您!我已经有了一个kotlinOptions来处理compileDebugKotlin,但需要这个额外的tasks.withType来解决kaptGenerateStubsDebugKotlin问题! - Bink
这是Kotlin Gradle插件中kapt部分的一个错误,从1.8.0版本引入。Jetbrains似乎不愿意修复它,尤其是因为kapt已经被KSP取代。https://youtrack.jetbrains.com/issue/KT-55947/Unable-to-set-kapt-jvm-target-version - BladeCoder

6

我认为按照错误信息所说使用jvmToolchain可以解决这个问题:

考虑使用JVM工具链:https://kotl.in/gradle/jvm/toolchain

使用以下版本和配置,我的项目运行良好。

  • Android Studio Flamingo 2022.2.1
  • AGP版本8.0.0
  • Gradle版本8.0
  • Kotlin版本1.8.0

在build.gradle中的配置:

kotlin {
    jvmToolchain(8)
}


android {

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

如果想了解更多细节,您可以在以下两个链接中查看相关官方文档和说明:

https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support

无法设置 kapt jvm 目标版本:

https://youtrack.jetbrains.com/issue/KT-55947


1
使用jvmToolchain(8)需要在您的计算机上安装JDK 8,这可能不被最新版本的Android Gradle插件支持。对于Android来说,最好使用默认工具链,并手动将jvmTarget设置为较低的版本。 - BladeCoder
@BladeCoder是正确的!我会接受他的答案。谢谢! - RumburaK
3
文档建议在 AGP 8.1.0-alpha09 之前不要使用 JVM 工具链。文档链接 - argenkiwi
警告意味着您应该使用编译选项而不是jvmToolchain,而不是同时使用。 - argenkiwi
据我理解,警告意味着建议用户使用AGP8.1.0-alpha09及以上版本,因为如果您使用低于此版本的话,您需要配置两个东西,而且这需要更多的工作(不应该使用这两种方式),所有这些都是由于错误引起的。此外,仅使用编译选项显然无法解决此问题。因此,解决此问题的方法是使用jvmToolchain或配置kapt jvmTaret使用任务作为RumburaK。这只是根据每个用户的实际情况做出的选择。警告并没有说使用会产生不良影响。 - yufeng wu
显示剩余4条评论

2
我在我的项目中使用以下版本,项目可以顺利构建:
- Android Studio Flamingo 2022.2.1 - AGP 版本 8.0.0 - Gradle 版本 8.0 - Kotlin 版本 1.8.0
为了消除错误,请将您的代码更改为以下内容:
android {
    ...
    compileOptions {
        sourceCompatibilityJavaVersion.VERSION_17
        targetCompatibilityJavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = '17'
    }
    ...
}

这里你可以看到与项目中应该使用的JDK版本兼容的Gradle 8.0.0兼容性表。

更新:

如果你不想改变你的Java版本并且在你的项目中使用Groovy DSL,那么@BladeCoder的答案是最佳解决方案。

然而,如果你正在使用Kotlin DSL,那么这个解决方案的语法会有一些不同:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs> {
    kotlinOptions {
        jvmTarget="1.8"
    }
}

1
我已经核实过,它可以在API 19及之前的API 16上正常工作。 - Victor Sklyarov
1
我也是,不过我想要理解。我从来没有在文档中看到过Java 17的提及,只有Java 8。可能与desugaring有关吗?但它是否支持所有语言特性呢?如果不支持,那么它会实际警告如果出现问题吗? - RumburaK
是的,由于解糖,旧版本的API也可以工作。我认为Java版本升级是为了改善Gradle构建性能。 - Victor Sklyarov
1
我成功在AVD管理器中使用API 16的Android 4.1(Google API)镜像在虚拟设备上运行了一个带有API 16和JDK 17的应用程序。我认为在物理设备上也不应该有问题。 - Victor Sklyarov
2
这不是一个适当的修复方法,它强制你使用目标兼容版本等于当前工具链版本,而这并不是大多数人想要的。 - BladeCoder
显示剩余2条评论

1
这对我完美地起作用了 ╰( ͡° ͜ʖ ͡° )つ──☆*:・゚

项目的 build.gradle 文件:

allprojects {    tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).configureEach {
        kotlinOptions {
            jvmTarget = "1.8"
            apiVersion = "1.8"
            languageVersion = "1.8"
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接