85

Is there a tool that will allow me to set breakpoints in a build.gradle file and step through tasks in a debugger?

Note: I believe that I'm asking a different question than similar stackoverflow questions about debugging Gradle plugins, where (presumably) the intent is to step through custom Groovy or Java plugin code located in a separate file. I want to set a breakpoint in a Gradle task in a simple build.gradle file, like...

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

...so that when I run gradle example I can inspect the context in a debugger.

(For those who would point me to IntelliJ...although JetBrains' website advertises that they support debugging Gradle scripts in IDEA UI, AFAICT this is untrue, as this was reported broken in IDEA13 EAP and hasn't been fixed in IDEA14. See Debugging Gradle build files in Intellij / Android Studio )

Is there any debugging tool that allows me to set a breakpoint in a build.gradle file, or is there something about the Gradle DSL that makes it fundamentally impossible to set breakpoints in a task such as my example, above?

Community
  • 1
  • 1
Mickalot
  • 2,431
  • 3
  • 22
  • 23

7 Answers7

56

There is the easier way:

just add in your command line -Dorg.gradle.debug=true --no-daemon

For example: gradle nameOfTask -Dorg.gradle.debug=true --no-daemon

Then you should start your IDE and run remote debugging with localhost port 5005, that all.

Gradle is waiting to you, because standard option server=y

org.gradle.debug

When set to true, Gradle will run the build with remote debugging enabled, listening on port 5005. Note that this is the equivalent of adding -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 to the JVM command line and will suspend the virtual machine until a debugger is attached.

Link to docs

Lore
  • 1,286
  • 1
  • 22
  • 57
user1722245
  • 2,065
  • 1
  • 18
  • 31
  • The documentation at https://docs.gradle.org/current/userguide/build_environment.html and the code at https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/java/org/gradle/process/internal/JvmOptions.java#L143 suggests that yes, this is essentially equivalent to the answer provided by @baptiste-mesta . – Mickalot Oct 04 '16 at 17:40
  • My gradle build doesnt stop and wait for debugger to become attached? – themathmagician Dec 22 '16 at 01:58
  • gradle should stop and wait for debugger, could you show me the cmd? – user1722245 Dec 27 '16 at 18:40
  • 3
    `-Dorg.gradle.debug=true` works the first time I run gradle (v3.5), but not the second. This seems to be a problem with the gradle daemon. So try running `gradle build -Dorg.gradle.debug=true --no-daemon`, this works every time for me. – neu242 Apr 28 '17 at 07:36
  • @neu242 I always get the output `To honour the JVM settings for this build a new JVM will be forked`. Don't you? I tried gradle 4.0 and 4.5.1. – koppor Feb 10 '18 at 18:19
  • 2
    The answer was written when there was gradle 3.4. I am not happy, that gradle is incompatible – user1722245 Feb 11 '18 at 16:44
  • I think you meant "Gradle is waiting to you, because standard option is suspend=y" – Sybuser Sep 22 '22 at 09:55
31

IntelliJ 2018.2 added the ability to debug Gradle scripts in a similar fashion to how you might run/debug other projects. You can see the announcement in the release notes here.

Here is a screenshot of some of the documentation from 2018.2:

IntelliJ documentation for debugging a Gradle script task

It does not yet support the kotlin-dsl (see gradle/kotlin-dsl/issues/39).

mkobit
  • 43,979
  • 12
  • 156
  • 150
16

Personnaly I do this when I need to debug build scripts:

Inside you terminal do

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

Then run your build

gradle clean install

Finally put some breakpoints and launch the remote debug configuration inside your IDE on the port 5005 and you’re good to go!

Baptiste Mesta
  • 579
  • 4
  • 8
  • android studio keeps telling me the following error when i try this: Unable to open debugger port (localhost:5005): java.net.ConnectException "Connection refused" – j2emanue Sep 05 '15 at 00:10
  • when you run gradle clean install does the build stops on "Listening for transport dt_socket at address: 5005" – Baptiste Mesta Sep 09 '15 at 08:21
  • 1
    The OP asked "Is there any debugging tool that allows me to set a breakpoint in a build.gradle file", so can you expand on "put some breakpoints"? – Noumenon Sep 19 '15 at 21:44
  • 3
    You are right, it's not working for breakpoints directly in build.gradle files. I was thinking that because I had in my sources the plugins that i wanted to debug. However you can put breakponts in the org.gradle.api.internal.project.AbstractProject on the configuration phase you want. e.g. put you breakpoint on org.gradle.api.internal.project.AbstractProject#dependencies(Closure configClosure) to stop the jvm before your closure depedencies { ...} is called – Baptiste Mesta Sep 21 '15 at 14:35
  • AndroidStudio/Idea gets attached to port, but it doesn't stop on breakpoints. And bp are displayed withing an X mark. I guess jetbrains just can't determine which source is linked to which file – deathangel908 Feb 11 '17 at 14:10
  • 4
    What does `launch the remote debug configuration inside your IDE` mean? How do you do that? – 11m0 Apr 04 '18 at 15:30
  • see here for intellij idea: https://www.jetbrains.com/help/idea/run-debug-configuration-remote-debug.html – Baptiste Mesta Apr 27 '18 at 13:09
  • How can i remove that options later? – Daniel Vilas-Boas Oct 11 '19 at 13:15
  • The export command will only affect the current shell session. Just open a new shell to "remove" that option – Baptiste Mesta Oct 15 '19 at 15:32
  • @11m0 [this page](https://www.jetbrains.com/help/idea/tutorial-remote-debug.html#541187ca) explains how to launch a `remote debug` session. TL;DR: choose Run > Edit Configurations... > Click the plus icon > select 'Remote JVM Debug' > accept the defaults and click 'Ok' – gMale Jun 15 '22 at 21:33
13

export GRADLE_OPTS does not work for me.

Try this:

1 Add remote debug config

enter image description here

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

2 add breakpoint in gradle

enter image description here

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

4 Attach debug in studio click icon enter image description here

enter image description here

Then the breakpoint stops !!

enter image description here

If console is not goiong, click this in debug pannel in studio. enter image description here

Victor Choy
  • 4,006
  • 28
  • 35
3

After reading various answers here the following steps will help you debug build.gradle to being able to break and investigate variables inside any custom task. I am using Eclipse remote debugging facilities

  1. Place this simple code where you want to break: try {throw new RuntimeException('Break');} catch (RuntimeException e) {}
  2. As recommended start your task with gradle mytask -Dorg.gradle.debug=true --no-daemon in the command prompt (don't have to do it in Eclipse)
  3. In Eclipse do Run -> Add Java Exception Breakpoint, choose RuntimeException and click "OK"
  4. Again in Eclipse go to Run -> Debug Configurations -> Remote Java Application and create new configuration that listens on localhost:5005. Name it whatever you want. Select a project that contains build.gradle you are debugging. Click Apply and Debug
  5. At this point the execution will start but will pause at the Exception-throwing line. And you can then start looking at your variables in the `Debug -> Variables" view, inspect the stacktrace, step through the code etc.
  6. No magic, alas, you will not see anything highlighted in build.gradle but you can pretty much guess where you are at
  7. Obviously on subsequent runs you don't need step 3 and in 4 you can reuse previously created configuration
  8. If you want to use this in the multiple places simply create a method, use different type of exception and feel free to enhance this idea in any way possible

For example:

void halt() {
    try {
        throw new RuntimeException('Break');
    } catch (RuntimeException e) {
        print('Paused')
    }
}

task iterateDeclaredDependencies {
    doLast {        
        Object configs = configurations.all
        halt();
        print(configs)
    }
}

enter image description here

Bostone
  • 36,858
  • 39
  • 167
  • 227
1
  1. run your command via Android Studio button

enter image description here

enter image description here

  1. wait it's completion or cancel it's execution
  2. ensure that your command shows here

enter image description here

  1. run debug with this button

enter image description here

i30mb1
  • 3,894
  • 3
  • 18
  • 34
  • 2
    (1) This will debug the app/tests which are run via this build, not the build itself, (2) the button you pointed to is only for debugging an already-running app, I believe you meant the one further to the left – Adam Burley Aug 11 '23 at 15:44
0

I use

set JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8989"

then 2 gradle processes are listening :

Listening for transport dt_socket at address: 8989
Listening for transport dt_socket at address: 8989

I can connect to both of them with 2 remote debug launch configurations in Eclipse although it's the same port.

Sybuser
  • 735
  • 10
  • 27