Debugging iteration (closures) in Groovy with IntelliJ IDEA
Asked Answered
H

2

9

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.

Hilarius answered 11/3, 2013 at 9:13 Comment(6)
Are you doing a 'step into'? (F7 shortcut)Lian
@Nebelmann If i 'step into' I have to step through a whole stack of Groovy classes setting up the iteration. I finally end up inside the loop, but it still a lot of trouble to get there.Hilarius
I'm afraid there's nothing you can do, then... As I understand, each is a closure, so if you step over it will skip the whole function, and if you step in you will have to deal with lots of 'noise', like in Java when you want to step into a Spring bean method call and end up in Proxies... Setting a breakpoint on the first line in your closure is the only solution I'm aware of. EDIT: I just found out IntelliJ's Debugger > Stepping options, which could prevent you from struggling with groovy's internals... It's worth giving it a try :)Lian
That is a shame. Since intelliJ works so well with Groovy, I would expect that the default behaviour would be to enter the closure. But I get your point, thanks.Hilarius
Nebelmann is correct, Step Over steps over a method call (which is each, or any other method taking closure) and doesn't go inside. If you have Settings | Debugger | Groovy | Do not step into specific Groovy methods, then Step Into might transfer you directly to the closure, or might not, depending on your Groovy version. Groovy runtime doesn't play well with stepping filters: jira.codehaus.org/browse/GROOVY-4063. See also youtrack.jetbrains.com/issue/IDEA-51344Lechery
The Eclipse Java debugger's step filtering has a global "Step Through" checkbox, which, when set, will take you to the first unfiltered line executed when you step into a filtered method. This seems like what you want- though it would be nice to be able to set it on a per-filter basis, rather than globally. I understand this isn't directly relevant, but it shows how such a feature might be designed.Frannie
C
6

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.

Citric answered 12/3, 2013 at 14:7 Comment(3)
Thanks for the ideas, they're helpful. Moving the "closure code" into a method doesn't really help me here though. What I REALLY would want is to just step into the closure, just like stepping into a Java loop.Hilarius
I agree. Hopefully, the IntelliJ devs will see this post and add this as a high-priority capability in an upcoming version. I know they watch Stack Overflow, and I know I've dealt with this issue with a whole pile of different people.Citric
Ten years later and it's still not working as expectedNunciature
C
0

I didn't understand how it works, but disabling this setting helped me

File->Settings->Debugger->Groovy->"Do not step into specific Groovy classes"

Chine answered 6/2, 2024 at 6:5 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.