Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 460
  • Last Modified:

Global exception handler for user interface thread

Hi,

I want to write a global exception handler for the main Java UI thread.
Something that traps any exceptions that weren't handled
at a lower level and pops up a message box and then allows the application
to continue.

It's that last part (about the app continuing) which presents the problem for me.
Otherwise I could simply put the try...catch in main().  That would report the
problem, but wouldn't allow the app to continue.

I see that ThreadGroup has an uncaughtException() method, but I can't see any
way to make use of this as I don't explicitly create the UI thread...so I don't
see how to subclass and replace this method and even if I could I'm not sure
it would solve the problem.

In case it matters, my app's main window is a JFrame.

Thanks in advance for any help,

Doug
0
dpearson
Asked:
dpearson
  • 6
  • 6
  • 2
1 Solution
 
objectsCommented:
> Otherwise I could simply put the try...catch in main().  

main() is a different thread from the GUI thread.


0
 
doronbCommented:
Hi,

The problem is that when an Exception is thrown and no one catches it inside the thread it was thrown from, it bubbles up and ends up interrupting main().

If you catch the Exception while still somewhere withing the run() method of the thread or the runnable object that threw the Exception, then you could respond to the Exception and let the Thread continue its task.

You would need to identify all the critical areas in your code and surround them with try/catch blocks which will display the dialog box with the Exception and then resume running when the user closes the dialog.

You could try the following though:

1) Define re-entry methods for each of the major threads in your application (for the UI thread this could be a method that shuts-down the GUI, fixes what needs to be fixed and re-displays the GUI again).

2) Store the re-entry methods in a Hashtable where the key would be [Thread-name/Exception-type/Class-name/Method-name].

3) Use the new (>=jdk1.4) StackTraceElement API to get the stack trace in your global Exception handler.

4) Anaylyze the stack trace and extract the combined key with which you can get the re-entry method.

5) Activate re-entry method which should fix the situation by any means needed (you decide what to do there) and re-start the Thread (this is a complete task in its own) or create a new Thread and restart it.

NOTE: This is just an idea, I have not testetd it yet. Going to do it, but not right now as I'm swamped with other issues (mainly work ;)

Hope this helps,
Doron
0
 
dpearsonAuthor Commented:
Hi Doron,

Certainly I could surround each top level function in the UI with a try-catch block...but that's an ever growing list (probably several hundred already) which is why I'd like to do something globally.

The idea of catching the exception and restarting the GUI is a clever thought, and I thihk your approach would work to do that, but unfortunately that doesn't really help the user's experience.  In practice in this app everything hangs from the UI thread, so restarting the GUI and relaunching the app is essentially the same thing.

Thanks for the idea anyway,

Doug
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
doronbCommented:
Hi Doug,

Perhaps you can wrap your ActionEvents with this:

  public class ActionListenerEx implements ActionListener {
    private Component cmp;
    private ActionListener listener;

    public ActionListenerEx(Component cmp, ActionListener listener) {
      this.listener = listener;
      this.cmp = cmp;
    }

    public void actionPerformed(ActionEvent e) {
      try {
        listener.actionPerformed(e);
      } catch (Exception ex) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos, true);
        ex.printStackTrace(ps);
        JOptionPane.showMessageDialog(cmp, baos.toString(), "Error", JOptionPane.ERROR_MESSAGE);
      }
    }
  }

This way, the Excpetion gets handled (printed for now) in a message box, but the program can continue without a problem.

Doron
0
 
dpearsonAuthor Commented:
Hi Doron,

That's another great idea.  The IDE I'm using (CodeWarrior) actually writes some of the action listener code for me, so I won't be able to use your idea directly, but perhaps I can adapt it.
I'll give it a try and see if it'll work.  I hadn't thought about subclassing the action listener at all--Java's events still aren't second nature to me (I'm more of a C++ guy).

Of course, this isn't quite as good as a truly global handler as other events (like mouse events) would need to be wrapped with something similar and their listeners are more scattered in the code...but half a loaf is better than no loaf!

Thanks,

Doug
0
 
objectsCommented:
> Certainly I could surround each top level function in the UI with a try-catch block

What are you referring to as top level fns in the UI?
0
 
dpearsonAuthor Commented:
Hi Objects,

By "top level functions" I mean the functions which respond to direct user input - menu choices, button clicks, mouse actions etc.

My app's a standard event driven system.  So it's basically sitting there doing nothing until the user takes some action.

My reason for wanting this "global exception handler" is that there are many places in my code where I check for invalid program states and throw some appropriate exception (e.g. IllegalArgumentException).

That's great for debugging and I'm very happy doing that.  But for a final release version, it would be nice to have something to catch these exceptions (which *should* never happen...but of course might still) and give the user the chance to save their data or whatever.

More than that I think it's an interesting issue for my Java programming in general.  I'm used to the C++ model of using error codes to indicate problems.  I think Java's exception model is superior and I'd like to make that exception model as robust as possible in my apps.

Doug
0
 
objectsCommented:
My initial thought is that you should not be throwing exceptions on the UI thread that will not be handled by your code. I cannot see any purpose to doing that.

As far as a global handler for the EDT I'll see what I can find.
0
 
objectsCommented:
You can define an exception handler using the system property sun.awt.exception.handler. This is a Sun hack and may be removed in the future but hopefully replaced with a better implementation (see RFE below):

System.setProperty("sun.awt.exception.handler",
   "mypackage.MyExceptionHandler");

package mypackage;

public class MyExceptionHandler
{
  public void handle(Throwable thrown)
  {
    // do your thing
  }
}


http://developer.java.sun.com/developer/bugParade/bugs/4714232.html
0
 
dpearsonAuthor Commented:
Very nice "objects".  From that property name I found all kinds of good discussion of this on Sun's site.

Clearly it's a hack but until a clean mechanism comes out I can live with that.

Interestingly, Microsoft added a solution in C# (or Java 3.0 as I like to think of it) very along the lines of the one requested in that RFE: the Application.OnThreadException() method.  I'm sure Sun will do the same soon.

Many thanks for everyone's help, lots of good ideas thrown out there.

Doug
0
 
objectsCommented:
Glad I could help :-)

http://www.objects.com.au/staff/mick
Brainbench MVP for Java 1
http://www.brainbench.com
0
 
dpearsonAuthor Commented:
Hey Mick,

So you're an Aussie -- and just when I was so impressed with your skills :)  Alas, I'm a Pom, although now living down the road from Microsoft.  I hope you're not a cricket fan...you murdered us in the last series.

Seriously though, I run a small software business up here in the Pacific Northwest and we're getting more Java work these days.  If we ever have too much to handle, I'll drop you a line and see if we can work something out.  Most of our work is remote anyway: different state, different country, what's the difference?

Thanks again,

Doug
0
 
objectsCommented:
> you murdered us in the last series.

Only the last series ;)
So when are you guys going to send the urn over?

> If we ever have too much to handle,
> I'll drop you a line and see if we can work something out.  

Hope business booms and I get the opportunity to work with you then :)

0
 
dpearsonAuthor Commented:
> Only the last series ;)
> So when are you guys going to send the urn over?

Haha.  You can have the urn once we burn some more stuff to symbolize the final true death of the game.  I think the clubhouse at Lords should do.

> Hope business booms and I get the opportunity to work with you then :)
You and me both.

Doug
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now