Search code examples
debugginggroovyintellij-ideaclosuresiteration

Debugging iteration (closures) in Groovy with IntelliJ IDEA


I have a code base with mixed Java and Groovy code. For iteration in the Groovy code, we tend to use closures:

String[] strings = ["First", "Second", "Third"]
strings.each { string ->
    println string
}

When I debug this in IntelliJ IDEA (v. 11) by stepping one row at a time, the code executing in strings.each() (that is println string) is stepped over. I can put a breakpoint at the println row, and I will be able to debug it, but it is a little workaround that would be nice to avoid.

Is there a way to configure intelliJ to not step over Groovy closures? There are no applicable options in File->Settings->Debugger->Groovy.

Edit:

To clarify what I expect intelliJ to do:

Say I have a Java style iteration like this:

for (String string : strings) {
    println string
}

If I use "Step over", the debugger steps into the iteration with no problems. I can the continue "stepping over" and still be in the loop until there are no more objects to iterate over. This is what I would expect for closures like above to.

It might not be a problem in a case with one or two closures where you manually have to set breakpoints. But if there are many, it would be really neat to "automatically" step into them.


Solution

  • I fully agree that there needs to be better Closure debugging support in IntelliJ, since what you are asking to do is not always as straightforward as it should be without jumping through some hoops.

    Like you've found, you can put a breakpoint on the println row, which will usually let you break within the Closure (but not always). Once you have a breakpoint, IntelliJ has a pretty powerful Conditional Breakpoint system, which will let you have much better control over when to break.

    Another route I've found useful from time to time is to take everything in these closures and toss it into a method that the closure calls, instead of having the code in the closure directly. This doesn't change the runtime behavior too much, and I've found that it gives me much more control over things. It also usually is an indication that I need to refactor as well, since it's already too painful to dig into that code.