How to debug a Gradle build.gradle file (in a debugger, with breakpoints)?
DebuggingGradleDebugging Problem Overview
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 https://stackoverflow.com/questions/22017433/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?
Debugging Solutions
Solution 1 - Debugging
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.
Solution 2 - Debugging
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:
It does not yet support the kotlin-dsl
(see gradle/kotlin-dsl/issues/39).
Solution 3 - Debugging
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!
Solution 4 - Debugging
export GRADLE_OPTS
does not work for me.
Try this:
1 Add remote debug config
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
2 add breakpoint in gradle
3 ./gradlew your task --stacktrace -Dorg.gradle.daemon=false -Dorg.gradle.debug=true
4 Attach debug in studio click icon
Then the breakpoint stops !!
If console is not goiong, click this in debug pannel in studio.
Solution 5 - Debugging
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
- Place this simple code where you want to break:
try {throw new RuntimeException('Break');} catch (RuntimeException e) {}
- 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) - In Eclipse do
Run -> Add Java Exception Breakpoint
, chooseRuntimeException
and click "OK" - Again in Eclipse go to
Run -> Debug Configurations -> Remote Java Application
and create new configuration that listens onlocalhost:5005
. Name it whatever you want. Select a project that containsbuild.gradle
you are debugging. ClickApply
andDebug
- 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.
- No magic, alas, you will not see anything highlighted in
build.gradle
but you can pretty much guess where you are at - Obviously on subsequent runs you don't need step 3 and in 4 you can reuse previously created configuration
- 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)
}
}