I'm currently using IntelliJ IDEA for Java development, but I'm also interested in answers targeting other IDEs or general concepts for debugging Java code. Because this is a feature I've missed in a number of IDEs, I'm unsure if I've missed a workflow concept when transferring my debug habits from other languages.
Let's say I'm writing some code in myapp.*
while using framework classes from somelib.*
. A typical stack trace may start in either package and may switch several times between them. Let's also say I'm debugging under the assumption that there are bugs in my code and that there aren't any in the library code. An example stack trace (showing only class names):
somelib.D (current stack frame)
somelib.C
myapp.Y
myapp.X
somelib.B
somelib.A
Normally, I'm not interested in the following types of exceptions and do not want the debugger to break on them:
Thrown in
somelib.B
and caught insomelib.A
. Either the library code is throwing exceptions to handle problematic state inside the library or to stop the application. In the latter case, I'm only interested in the exception message which hopefully tells me what's wrong.Thrown in
somelib.D
and caught insomelib.C
. The library code may use exceptions as a form of logic where a certain action is tried and an alternative route is taken in the case of a problem or where my code is notified by the problem by other means (e.g. returning a null reference where appropriate).
Types of exceptions I am interested in:
Thrown in
somelib.C
orsomelib.D
and not caught insomelib.C
orsomelib.D
. Here I want the debugger to break on the line inmyapp.Y
where I call the code fromsomelib.C
.Thrown in
myapp.X
ormyapp.Y
, either caught or uncaught. Here I want the debugger to break on the line the exception is thrown.
IntelliJ IDEA gives me the options to select wether I want to break on caught or uncaught exceptions, or both and to restrict the location where the exception is thrown to a set of classes. These options don't help much as I normally want to break on any exception, wether caught or uncaught, as long as code I've written is between the place it's thrown and the place it's caught, eventua开发者_如何学运维lly.
You can create two exception breakpionts:
- An Exception breakpoint that hit whenever there is an exception in
myapp.*
(caught or uncaught). Use Class Filter for this purpose (look at here for class filters). - An Exception breakpoint that hit whenever there is an uncaught exception in either 'somelib.C1
or
somelib.B`. Again use class filters to restrict the breakpoint.
In IntelliJ you can define a condition
on an exception
break point. The condition is just Java code executed at the time the breakpoint is hit, so the exception object would be in-scope during the condition check. You could call getStackTrace()
on the exception and decide if it is an exception that you are interested in by looking at each frame on the stack. If you aren't interested, then your condition fails, and the breakpoint is skipped.
It seems to be impossible to do exactly what I wanted in a convenient way. At the time of this question I was in the process of learning Java and teaching it to my fellow students, so a simple solution would have been favorable.
But with my current experience it seems reasonable to use the following approach:
- Put
catch (Trowable t)
around each thread body, i.e. at the top level ofRunnable.run()
andstatic main(String[])
and log these "uncaught" exceptions to the console.- Care needs to be taken to not accidentally catch checked exceptions with these "catch-all" handlers, but to handle them as part of program logic.
- When starting to debug, do not create any exception breakpoints.
- As soon as an exception is logged to the console, create an exception breakpoint for it and try to make it get thrown again.
- This should only happen unchecked exceptions (i.e. subclasses of
RuntimeException
) as other exceptions have to be explicitly caught and handled anyway. - As catching and handling unchecked exceptions normally isn't part of a program's logic, creating these exception breakpoints without constraints on the place it's thrown should not catch any "false positives".
- This should only happen unchecked exceptions (i.e. subclasses of
An alternative is to skip the last two steps and instead create an exception breakpoint for RuntimeException
. But this has a higher change of catching exceptions that are caught as part of the program logic.
Use Eclipse! Using Eclipse you can filter where the exception should stop the debug using breakpoint properties.
精彩评论