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

9

我正在编写一个注解处理器,并最近从使用默认的annotationProcessor类型转换为kapt,使用kotlin-kapt插件。

我通过使用命令进行调试:

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

完整的指导请看这里:https://dev59.com/Lmoy5IYBdhLWcg3wZdGr#42488641

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

我的kotlin版本是1.1.2-3

4个回答

11

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

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

我需要对远程配置进行更改吗? - M Dapp
我尝试了以下命令:./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中没有任何更改,运行不成功... - M Dapp
请重启Kotlin和Gradle守护进程。您可以使用“jps”命令找到正在执行的所有Java进程。同时,请确保守护进程JVM选项和IDEA中的调试端口相同(5005)。 - yanex
我现在明白了...你还必须等到Kotlin编译器守护程序启动后才能附加调试器。 - M Dapp
5
我之前在 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"。在命令行中运行此命令,然后当您感到舒适时,再附加远程调试配置,而不是在 app:kaptDebugKotlin 任务或其他任务期间。 - Den Drobiazko
显示剩余2条评论

3

我刚试图调试一个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连接。


2
另一个回答通常是正确的,但我发现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 并点击调试按钮,这样我就可以很好地使其附加。


1
这个在最新版本的Android Studio/Kotlin上还能用吗?我正在尝试按照这种方法操作,但是一直出现以下错误:
  • 无法打开调试器端口(localhost:5005):java.net.BindException“地址已在使用中(绑定失败)”
我已经调用了jps来检查所有正在运行的进程,据我所知没有任何进程在运行。
- cmota
从kotlin 1.7.20开始,其他答案对我不再起作用,唯一可行的方法是添加标志“-Dorg.gradle.debug=true -Dkotlin.compiler.execution.strategy=in-process”。 - konakid

2
自 Kotlin 1.2.60 开始,您可以在 gradle.properties 文件中包含 kapt.use.worker.api=true 来使用 Gradle Worker API 进行 kapt。这样做的好处是,kapt 任务可以使用普通的 gradle debug 参数进行调试(./gradlew <task> -Dorg.gradle.debug=true --no-daemon),而不需要特定的 kotlin 参数。

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