If you’ve been a regular reader of my blog you will probably know that I am not Eclipse’s biggest cheerleader. “I hate it” might be a bit strong, but not by much. Recently though, I’ve been forced to use it more and more. Frankly, if you want to work in cross platform Java, especially using Google’s tools, you are pretty much forced to these days. One of my biggest annoyances is the obtuseness of the interface. Today I am going to show one such example.
One of the things about working with LibGDX in Eclipse is it uses a fair number of threads and when an exception is thrown, if it wasn’t directly in your code, you are kinda screwed. Look at this example, from code I am currently working on:
What I see here is I caught a “Throwable” derived exception and am throwing a RuntimeException in turn. I can look up in the thread stack trace to see where it was thrown ( although the code above makes it pretty obvious, but stay with me for a moment).
If I look at the debug window, I can see that stack trace, to see where the exception came from:
There is a really useful piece of information here ( the exception type was GdxRuntimeException ), but the stack trace itself is pretty flat. That is because each stack is thread specific and frankly, we just created this thread. So our stack basically consists of Thread.run() and well, that’s about it. We can tell by our code that the exception was thrown somewhere in LwjglApplication.mainLoop() but that is all we’ve got to work with. We could set a breakpoint in mainLoop and run until it triggers, but that is extremely annoying. What we want to do instead is stop execution when the exception is THROWN, not when it is caught.
This can be done in Eclipse, but in the way of Eclipse, it certainly isn’t intuitive. Since we know our exception type is GdxRuntimeException, we will trigger it to stop execution whenever one of those is thrown. Let’s look at how.
In Eclipse, switch to Debug Perspective.
Now locate the Breakpoint panel and the J! icon. ( Intuitive eh? )
In the resulting dialog, in the Choose an exception text field, enter GdxRu*. The asterisk is a wildcard, so it will return any Exception that start with GdxRu. Click OK.
By the way, the default is *Exception*, meaning breakpoint on all Exceptions with the word Exception in them. That sounds wonderful and all, problem is, it simply doesn’t work… yay Eclipse. There is probably some 5 year old bug report somewhere explaining why.
OK, bitching aside, your exception list should now contain an entry for GdxRuntimeException:
Now right click the Exception and select Breakpoint Properties…
Make sure the following settings are enabled:
Now when you run the code again, the debugger will stop where the exception is thrown.
Wahoo! Now that information is about 1000x more useful. Now we see where our Exception is actually being generated.
A couple tips.
You can toggle the breakpoint exception off and on using the checkbox next to it in the breakpoint window:
Remember how I said earlier that setting *Exception* as the breakpoint simply doesn’t work? So, what do you do if you want to stop on all exceptions? You set a breakpoint on Throwable and set “Subclasses of this Exception” to true, like so:
Warning though, Exceptions are commonly thrown, so expect hit a whole lot of breakpoints!
I know this information is probably common knowledge to people that live in Eclipse, but for those of us that come from other IDEs, its frustrating until figured out, and certainly not intuitive to figure out. Thus this post, hope a few of you found it useful.