Question

Just a note: I know that in Java finally block should never throw exceptions, otherwise it's [very, very, very] bad practice.
I know that I should use try-catch inside finally to handle (e.g. log or ignore) all exceptions and prevent them from propagating.
I know that Java 7's Throwable has getSuppressed method, but I target Java 5 & 6.

Problem: In Java, in try-finally if an exception (name it A) is thrown by try block, control reaches finally block (in case of no exception it reaches it also, but it's not interesting in this question). Then, if finally block throws an exception (name it B), exception A is suppressed, or masked/swallowed, and exception B is propagated to the caller.

Question: Can i somehow detect the situation when one exception is suppressed by another and log/record the first one?
... I spent too much time reasoning why particular exception has been thrown and not knowing what has really happened.

Rationale: Often problematic try-finally blocks are coded in a library (today it was Hibernate), so I'm not able to modify them.

Solution constraints: As I noted at the beginning, possible solution should not relay on Java 7, but, on the other hand, does not need to be production grade (being such would be a bonus). AOP is an option here.

(Please don't post trivial answers like "use Java 7 for development":)

Was it helpful?

Solution

The problem I think is that even with AOP you can not intercept the exception consumption process. With AOP you could capture, say, all of the exceptions that are created, but you can't know when they're consumed.

For example:

try {
    ...
} catch (Exception e) {
    log.boom("Ouchies happened here", e);
}

Not every exception is re-thrown.

However, at a certain level MOST exception ARE, eventually, thrown so that the caller can handled them.

So, given that you will likely "leak" exceptions anyway, the game is to try and find the "leaking" exceptions.

Using AOP you can while away each Exception as it is created (whether you can do this at the Exception level, or have to do it at the individual class level, I can't say -- not that familiar with AOP in practice in this case).

Once you're capturing exceptions as they are created, then you start wrapping method calls via AOP. When you do this, you can capture the exceptions being thrown by the method.

So, with a little work, you know when returning from a method a) which exceptions were created and b) which were thrown. If you walk the exception "caused by" tree of the returned exception from the method, you can throw these out of the "exceptions created by this method" list. The remainder are the leaks.

Ideally, after a little analysis, you'll be able to identify which ones are simply not thrown (but handled in some other way), and which ones are actually shadowed by your finally blocks.

It's imperfect, and most certainly I wouldn't use it in production (I'd simply have to put to much work in to all of the race condition around recording stuff and such. More work than I'd want to do for this kind of debugging, frankly). But it might give you the information you are looking for, especially when used sparingly across a small domain of classes.

OTHER TIPS

There's a JNI method named "ExceptionCheck()" which, not surprisingly, checks for a pending exception. You can call it in the middle of a native method to see if some prior call has thrown an exception which is waiting around for the JNI method to return before it's actually thrown. I wonder if you could call a native method from finally, then tried to use ExceptionCheck to see if there's a pending exception, if that'd work. I have no idea whether it would but I'd say it's worth a try.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top