How to report all exceptions in JVM, be it own or third-party code?
Is there a way to log all exceptions happening within JVM?
A system is built from a big number of smaller components provided by different groups. All of them are running within the same JVM (under Weblogic).
Error reporting policies are rather different in those groups, so sometimes we have cases of suppressed exceptions, which makes troubleshooting very hard. At the same time, I noticed that JDB is able to intercept any exception happening in the code, no matter where.
I'd like to use the same facility JDB uses in DEV/SIT/UAT environment to shorten issue resolution time. In PTE and PROD though the facility shall not only be turned off, but
- create no performance impact
- require no code change for turning it off.
Of course, I can have JDB connected to every instance of ser开发者_如何学Gover running in DEV/SIT. It's feasible, I guess... but there are two main downside:
- it makes configuration more complex
- JDB stops when an exception has occured; need a script or something to let it continue
So I wonder is there any method that does it, e.g. Runtime.traceExceptions(...)?
As far as I know there is no official Java API for this besides the debugging API which could be used also from inside the VM that is about to be 'debugged'.
An easier quick and dirty way to get notified of every exception that is created at runtime is to hack some tracing code directly into the constructor(s) of the Throwable class, compile it and put it into the bootclasspath
before the rt.jar. This is of course nothing you should do in a release version but it can be very helpfull to analyse code that catches exceptions somewhere and doesn't report them properly.
In response to the comments:
Regarding the Debugger API: The last time I did something like this I used the JVMDI to build a native JNI/JVMDI dll and accessed it from inside the VM. It works and lets you do all sorts of wired things that Java normally doesn't offer but I would consider this even more of a hack than using a patched Throwable class. Besides that, the JVMDI has been deprecated and was replaced with JVM TI since Java 1.6. I don't know if and how you can do something like this with this new Debugger API as well.
Using a modified Throwable is fast, easy to get right, doesn't impose any performance degeneration by itself and also not even really hackish if you are in control over the execution environment. You could think of as some kind of AOP. ;) But I would still only use it to find otherwise hard to detect bugs and not in production code or only as a last resort. Something like this should surely not be considered as part of the design. The best long term approach would be to get all your development groups to agree on some common exception treatment.
Also FindBugs can help a lot if you decide to do a code review to find all these spots where exceptions get caught and not reported.
I would probably un-jar the JDK, modify "Exception" to log your exception and then re-jar it.
It's a pretty reasonable solution and won't cause any problems--the JDK classes are, for the most part, just standard java classes.
You might be able to do it without modifying the JDK by manipulating the class path to read your version of "Exception" before reading the JDK's version--that way it wouldn't be as difficult to distribute.
GDB is designed for GCC built programs, If you are debugging a Java application I suggest you use the Java Debugger in your IDE. It can be used to trap any exception thrown.
Note: some of the libraries throw exceptions during start up normally and imagine Weblogic has some of its own.
There's a project on Fedora - ABRT - automatic bug reporting tool.
It also reports uncaught JVM exceptions.
Right now (2013), an effort is started to make it also catch JBoss AS / EAP / WildFly exceptions.
Stay tuned to know when it comes: https://fedorahosted.org/abrt/milestone/Support_for_JAVA_exceptions
精彩评论