By Doug Simon on Jun 22, 2011
Occasionally you may find yourself in a Java application environment where exceptions in your code are being caught by the application framework and either silently swallowed or converted into a generic exception. Either way, the potentially useful details of your original exception are inaccessible. Wouldn't it be nice if there was a VM option that showed the stack trace for every exception thrown, whether or not it's caught? In fact, HotSpot includes such an option:
-XX:+TraceExceptions. However, this option is only available in a debug build of HotSpot (search
TraceExceptions). And based on a quick skim of the HotSpot source code, this option only prints the exception class and message. A more useful capability would be to have the complete stack trace printed as well as the code location catching the exception. This is what the various
TraceException* options in in Maxine do (and more). That said, there is a way to achieve a limited version of the same thing with a stock standard JVM. It involves the use of the
-Xbootclasspath/p non-standard option. The trick is to modify the source of
java.lang.Exception by inserting the following:
Then every constructor simply needs to be modified to call
log() just before returning:
You now need to compile the modified
Exception.java source and prepend the resulting class to the boot class path as well as add
-DTraceExceptions to your
java command line. Here's a console session showing these steps:
It's worth pointing out that this is not as useful as direct VM support for tracing exceptions. It has (at least) the following limitations:
- The trace is shown for every exception, whether it is thrown or not.
- It only applies to subclasses of
java.lang.Exceptionas there appears to be bootstrap issues when the modification is applied to
- It does not show you where the exception was caught.
- It involves overriding a class in rt.jar, something should never be done in a non-development environment.