【问题标题】:How to debug a Gradle build.gradle file (in a debugger, with breakpoints)?如何调试 Gradle build.gradle 文件(在调试器中,带有断点)?
【发布时间】:2015-04-10 20:05:51
【问题描述】:

是否有工具可以让我在 build.gradle 文件中设置断点并在调试器中逐步执行任务?

注意:我相信我提出的问题与有关调试 Gradle 插件的类似 stackoverflow 问题不同,其中(可能)意图是逐步执行位于单独文件中的自定义 Groovy 或 Java 插件代码。我想在一个简单的 build.gradle 文件中的 Gradle 任务中设置断点,例如...

task example {
   println "I want to set a breakpoint here"
}

...这样当我运行 gradle example 时,我可以在调试器中检查上下文。

(对于那些将我指向 IntelliJ 的人......虽然 JetBrains 的网站宣传他们支持在 IDEA UI 中调试 Gradle 脚本,但 AFAICT 这是不真实的,因为据报道这在 IDEA13 EAP 中被破坏并且尚未修复IDEA14. 见Debugging Gradle build files in Intellij / Android Studio)

是否有任何调试工具可以让我在 build.gradle 文件中设置断点,或者 Gradle DSL 是否有一些东西让我根本不可能在上面的示例中设置断点?

【问题讨论】:

    标签: debugging gradle


    【解决方案1】:

    有更简单的方法:

    只需在命令行中添加-Dorg.gradle.debug=true --no-daemon

    例如: gradle nameOfTask -Dorg.gradle.debug=true --no-daemon

    然后您应该启动您的 IDE 并使用 localhost 端口 5005 运行远程调试,仅此而已。

    Gradle 正在等待你,因为标准选项 server=y

    org.gradle.debug

    当设置为 true 时,Gradle 将在启用远程调试的情况下运行构建,侦听端口 5005。请注意,这相当于将 -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 添加到 JVM 命令行,并将暂停虚拟机,直到附加调试器.

    Link to docs

    【讨论】:

    • docs.gradle.org/current/userguide/build_environment.html 的文档和github.com/gradle/gradle/blob/master/subprojects/core/src/main/… 的代码表明是的,这基本上等同于@baptiste-mesta 提供的答案。
    • 我的 gradle 构建没有停止并等待调试器连接?
    • gradle 应该停止并等待调试器,你能告诉我 cmd 吗?
    • -Dorg.gradle.debug=true 在我第一次运行 gradle (v3.5) 时工作​​,但不是第二次。这似乎是 gradle 守护进程的问题。所以尝试运行gradle build -Dorg.gradle.debug=true --no-daemon,这对我来说每次都有效。
    • 答案是有gradle 3.4的时候写的。我不高兴,那个 gradle 不兼容
    【解决方案2】:

    IntelliJ 2018.2 添加了以与运行/调试其他项目类似的方式调试 Gradle 脚本的功能。您可以在发行说明here 中查看公告。

    以下是 2018.2 部分文档的截图:

    它还不支持kotlin-dsl(见gradle/kotlin-dsl/issues/39)。

    【讨论】:

      【解决方案3】:

      当我需要调试构建脚本时,我个人会这样做:

      在你的终端里面做

      export GRADLE_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
      

      然后运行你的构建

      gradle clean install
      

      最后在 IDE 的 5005 端口上放置一些断点并启动远程调试配置,一切顺利!

      【讨论】:

      • android studio 在我尝试此操作时不断告诉我以下错误:无法打开调试器端口 (localhost:5005): java.net.ConnectException "Connection denied"
      • 当您运行 gradle clean install 时,构建是否会在“Listening for transport dt_socket at address: 5005”时停止
      • OP 询问“是否有任何调试工具可以让我在 build.gradle 文件中设置断点”,那么您可以扩展“放置一些断点”吗?
      • 你是对的,它不适用于直接在 build.gradle 文件中的断点。我在想,因为我的源代码中有我想要调试的插件。但是,您可以在所需的配置阶段将断点放在 org.gradle.api.internal.project.AbstractProject 中。例如在 org.gradle.api.internal.project.AbstractProject#dependencies(Closure configClosure) 上设置断点以在调用闭包依赖项 { ...} 之前停止 jvm
      • launch the remote debug configuration inside your IDE 是什么意思?你是怎么做到的?
      【解决方案4】:

      export GRADLE_OPTS 不适合我。

      试试这个:

      1 添加远程调试配置

      -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

      2 在gradle中添加断点

      3 ./gradlew your task --stacktrace -Dorg.gradle.daemon=false -Dorg.gradle.debug=true

      4 在工作室中附加调试 点击图标

      然后断点停止!!

      如果控制台未启动,请在工作室的调试面板中单击此按钮。

      【讨论】:

      • 对我不起作用......它在无限时间内什么都不做。
      【解决方案5】:

      在此处阅读各种答案后,以下步骤将帮助您调试 build.gradle 以破解和调查任何自定义任务中的变量。我正在使用 Eclipse 远程调试工具

      1. 把这个简单的代码放在你想中断的地方:try {throw new RuntimeException('Break');} catch (RuntimeException e) {}
      2. 建议在命令提示符中使用 gradle mytask -Dorg.gradle.debug=true --no-daemon 开始您的任务(不必在 Eclipse 中执行此操作)
      3. 在 Eclipse 中执行 Run -> Add Java Exception Breakpoint,选择 RuntimeException 并单击“确定”
      4. 再次在 Eclipse 中转到 Run -> Debug Configurations -> Remote Java Application 并创建侦听 localhost:5005 的新配置。随意命名。选择一个包含您正在调试的build.gradle 的项目。点击ApplyDebug
      5. 此时将开始执行,但会在抛出异常的行暂停。然后您可以开始在“Debug -> Variables”视图中查看您的变量,检查堆栈跟踪,逐步执行代码等。
      6. 没有魔法,唉,你不会在build.gradle 中看到任何突出显示的内容,但你几乎可以猜到你在哪里
      7. 显然,在后续运行中,您不需要第 3 步,而在第 4 步中,您可以重复使用之前创建的配置
      8. 如果您想在多个地方使用它,只需创建一个方法,使用不同类型的异常,并随时以任何可能的方式增强这个想法

      例如:

      void halt() {
          try {
              throw new RuntimeException('Break');
          } catch (RuntimeException e) {
              print('Paused')
          }
      }
      
      task iterateDeclaredDependencies {
          doLast {        
              Object configs = configurations.all
              halt();
              print(configs)
          }
      }
      

      【讨论】:

      • 虽然我更喜欢从第 1 点开始使用单行而不是提取方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多