views:

197

answers:

4

I'm developing a new Java desktop application and would like to include a crash reporting facility - you know the kind of thing - program crashes, box pops up asking user to click okay to send it, etc.

I'm comfortable with how the error will be sent back to our servers - probably via a simple web service. What I'm more unsure about is how the mechanism for capturing the failure should be implemented?. I would welcome any advice from anyone that has implemented something similar.

A: 

I see three cases:

1). Catastrophes. The JVM itself is either dead or dying. You canot assume that any of your code will be able to work - for example you can't allocate any memory. Hence in this case you can't reasonably hope to be able to send any diagnoistics. The best you can hope for is to have some diagnistics such as core dumps left in the ashes of the dead program.

In this case you could on startup of a new run look for such debris and suggest that the user gather it or, rather more effort attempt to assemble a dignaist package yourself.

2). The low-level applcation code does not catch an exception, perhaps a RunTime exception such as a NullPointer exception. In this case you could in your main (assuming you have one) you could catch Exception and have some hope your that your Crash Reporter code will work. Pass the exception, and it's stack trace, to the Crash Reporter.

3). You low level code catches something really unhealthy. Not enough to terminate process, but worth reporting. Here you not only have the exception to hand but other contextual information. We have rather more to send to the Crach Reporter.

djna
A desktop application effectively has no main method. The main thread ends when the frame is shown (and whatever else it does until the method finishes).
Yishai
In most cases yes, that's why I said "if you have one", but there are some non-ui desktop apps that can have a main. Anyway it would be good to know what you would recommend in the case when have no main.
djna
A: 

I don't know if this is the best that Java currently has to offer, but this is what I did a while back.

First all interesting activity likely to crash was dispatched via a command pattern. This application consisted of hitting an application server over the internet, so a lot could go wrong. The exceptions were caught by the command dispatcher and the appropriate result displayed to the user (generally showing an error dialog followed by a shutdown and an e-mail sent about the crash).

Second, a custom event queue was used in Swing to catch any exceptions that happen on the event thread. I would hope that Java has a better solution by now, but basically when an exception happened you had to check if your code was involved, otherwise some Swing bugs could crash your application, which isn't pleasant. And of course recursion had to be checked for (the crash repeating itself over and over again as you try to display a message to the user).

By the way, most any crash will keep your JVM going, including out of memory errors, enough to send an e-mail in most cases, as after an out of memory error generally the error releases enough of the stack (and therefore heap) to allow for further garbage collection and letting your code live. But in such an event you should still exit quickly. IDEA keeps going after an out of memory error, but often isn't functioning well. They would be better off exiting, IMO.

You push a new Queue with the following and subclass EventQueue to link in your behavior.

 Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue);
Yishai
A: 

Use Thread.setUncaughtExceptionHandler and the static Thread.setDefaultUncaughtExceptionHandler to (attempt to) report exceptions to your logging system.

Ken
+1  A: 

There is a command line option you can give the JVM that will run a batch file after the JVM crashes with a memory dump. All you do is create a external program that does the error reporting and then use the JVM option to send the core dump in email using the utility you made.

-XX:-HeapDumpOnOutOfMemoryError -XX:OnError="<cmd args>;<cmd args>"
djangofan
of course, you would want to combine this method with a runtime error reporting capability also...
djangofan