使用 kapt 和 gradle 时无法调试注释处理器

Posted

技术标签:

【中文标题】使用 kapt 和 gradle 时无法调试注释处理器【英文标题】:Can't Debug an Annotation Processor when using kapt and gradle 【发布时间】:2017-10-22 10:47:07 【问题描述】:

我正在构建一个注释处理器,我最近使用 kotlin-kapt 插件从使用默认的 annotationProcessor 类型切换到 kapt。

我正在使用命令调试我的处理器

./gradlew --no-daemon -Dorg.gradle.debug=true :app:clean :app:compileDebugJavaWithJavac

(此处的完整说明:https://***.com/a/42488641/502463)

然后运行远程调试配置。当我使用 annotationProcessor 时,我可以打断点,并且调试得很好。使用 kapt,我的处理器运行,但我无法调试它。没有触发断点。

我的 kotlin 版本是 1.1.2-3

【问题讨论】:

【参考方案1】:

您实际上想要调试 Kotlin 编译器守护进程,而不是 Gradle 守护进程。以下是传递所需 JVM 参数的方法:

./gradlew <tasks> -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=n"

【讨论】:

我是否也需要更改远程配置? 我试过了:./gradlew --no-daemon -Dorg.gradle.debug=true :app:clean :app:compileDebugKotlin -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp :transport=dt_socket\,address=5005\,server=y\,suspend=n" IDE 没有变化,但没有运气... 请重启 Kotlin 和 Gradle 守护进程。您可以使用jps 命令找到所有正在执行的Java 进程。还要确保守护进程JVM选项和IDEA中的调试端口相同(5005)。 我现在明白了...您还必须等待附加调试器,直到 kotlin 编译器守护进程启动 我还在努力调试 IntelliJ Idea 中的非 android 项目。一位同事建议 kotlin 可能正在运行它自己的守护进程,这会阻止在适当的时间附加调试配置。在没有守护程序的情况下运行 kotlin 可修复问题:./gradlew clean :sample:build --no-daemon -Dorg.gradle.debug=true -Dkotlin.compiler.execution.strategy="in-process" -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=n"。在 CLI 中运行它,然后在您感觉舒适时附加远程调试配置,而不是在 app:kaptDebugKotlin 任务期间或其他任何时候【参考方案2】:

我刚刚尝试调试 Kotlin 注释处理器并找到了这篇文章。 您可以通过传递 suspend=y 来告诉 JVM 等待调试器

我现在做的是从命令行开始构建:

./gradlew --no-daemon clean build -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=y"

然后通过远程配置与 Intellij 连接。

【讨论】:

【参考方案3】:

另一个答案通常是正确的,但我发现https://medium.com/@daptronic/annotation-processing-with-kapt-and-gradle-237793f2be57 有助于了解更多细节。

你可以运行这样的东西

./gradlew --no-daemon clean compileDebugKotlin -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=n"

或者如果你想运行一个特定的模块

./gradlew --no-daemon :modulename:clean :modulename:compileDebugKotlin -Dkotlin.daemon.jvm.options="-Xdebug,-Xrunjdwp:transport=dt_socket\,address=5005\,server=y\,suspend=n"

棘手的部分

在附加调试器之前,我们实际上需要等待 Kotlin 编译任务开始,它不会像 java 那样暂停并等待您附加调试器。

所以您想要监控您的构建并寻找任务: :app:kaptDebugKotlin 当你看到它时,立即前往你的 IDE 并在你的远程配置上点击调试。如果您不及时附加,任务将继续进行。您有几秒钟的时间来解决这个问题,但要让这一切正常运行是一场竞赛。

我花了很长时间才弄清楚并开始工作。现在,只要我运行命令,我就去 IDE 并混合调试器按钮,我很幸运能够以这种方式附加它。

【讨论】:

嗯...这仍然适用于最新版本的 Android Studio/Kotlin 吗?我正在尝试遵循这种方法,并且不断收到:-无法打开调试器端口(localhost:5005):java.net.BindException“地址已在使用中(绑定失败)”我已经调用jps来检查所有正在运行进程,据我所知没有运行。【参考方案4】:

从 Kotlin 1.2.60 开始,kapt 支持使用 Gradle Worker API,方法是在您的 gradle.properties 文件中包含 kapt.use.worker.api=true

额外的副作用是 kapt 任务可以使用普通的 gradle 调试参数 (./gradlew &lt;task&gt; -Dorg.gradle.debug=true --no-daemon) 进行调试,并且不需要特定的 kotlin 参数。

【讨论】:

以上是关于使用 kapt 和 gradle 时无法调试注释处理器的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候需要在 Gradle 依赖项中使用 Kapt?

自定义Gradle plugin Java AnnotationProcessor 和 Kotlin Kapt 断点调试

Kapt 注释处理 - 如何显示完整的堆栈跟踪

什么是 Android kapt 及其用法?添加依赖项时,Gradle 中的注解处理器和 kapt 有什么区别?

数据绑定注释处理器 kapt 警告

Android - 使用 gradle 3.2.1 构建数据绑定和 kapt 失败