i9rspw
Last Updated: February 25, 2016
·
319
· davewatts

Logging unlogged Exceptions in Eclipse

The worst kind of people write code like this:

try {
   foo();
} catch(FooException e)
    System.out.println("An exception occurred");
}

Slightly less terrible people might indicate that it was a FooException, or even go as far as to include any message in the exception. Even if they are so inclined, the Exception itself, including its creamy stack trace center, is lost.

If this abomination was perpetrated by the schmuck down the hall, it's bad enough. At least you can clip them around the ear and make them fix it [1]. But when this is in something you can't fix and rebuild easily, possibly 3rd party code, you're in trouble.

If you can attach the Eclipse debugger to the JVM, and you have access to the source, all is not lost.

  1. Debug the program
  2. Find the exception
  3. Set a conditional breakpoint
  4. Execute the code

Debug the program

If you're writing your code in Eclipse, just run it from there in debug mode. If the code is running outside Eclipse, see Remote Debugging A Java Application

Find the exception

Open up the source where the Exception occurs and search for the text of the log message. Alternatively, set an Exception breakpoint and run the offending use case again. Eclipse will stop when the specified exception is thrown.

Set a conditional breakpoint

Normally when you create a breakpoint, execution will stop whenever that line of code is executed. Conditional breakpoints only fire in the event some condition is met, such as a specific parameter being passed into a method.

These conditions are written as Java and evaluated within the JVM. We can take advantage of this to inject some code into the running JVM .

Find a line of code where the exception object exists, eg

System.out.println("An exception occurred");

Set a breakpoint on this line, and then right click on the blue breakpoint indicator. In the context menu, select "Breakpoint Properties"

In the dialog, set the Conditional check box. This will enable the text box below.

In the text box, enter the following [1]

LOG.error("Logging exception: " + e.getMessage(), e);
return true;

Execute the code

Now debug the exception-causing code again. This time, the breakpoint's condition will be evaluated, meaning the exception will be logged, and then execution will be paused. You can now consult the log to find the stack trace you should always have had, enabling you took up the source of the problem

Footnotes

1: Like this:

try {
   foo();
} catch(FooException e)
    System.out.println("An exception occured while fooing: " + e.getMessage());
    e.printStackTrace();
}

That wasn't so hard, was it? If it had been done like that in the first place, I wouldn't have even needed to write this tip.

2: Depending on the library's logging system, you may need to tweak this. The above assumes a log4j logger called LOG. At worst, you can probably use the following

System.err.println("Logging exception: " + e.getMessage());
e.printStackTrace();
return true;