?
Solved

Global exception handler for user interface thread

Posted on 2003-03-28
14
Medium Priority
?
457 Views
Last Modified: 2011-04-14
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
Comment
Question by:dpearson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
  • 2
14 Comments
 
LVL 92

Expert Comment

by:objects
ID: 8229554
> Otherwise I could simply put the try...catch in main().  

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


0
 
LVL 9

Expert Comment

by:doronb
ID: 8233347
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
 
LVL 28

Author Comment

by:dpearson
ID: 8234479
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 9

Expert Comment

by:doronb
ID: 8234819
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
 
LVL 28

Author Comment

by:dpearson
ID: 8234955
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
 
LVL 92

Expert Comment

by:objects
ID: 8235389
> 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
 
LVL 28

Author Comment

by:dpearson
ID: 8235530
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
 
LVL 92

Expert Comment

by:objects
ID: 8235605
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
 
LVL 92

Accepted Solution

by:
objects earned 1000 total points
ID: 8235660
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
 
LVL 28

Author Comment

by:dpearson
ID: 8235812
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
 
LVL 92

Expert Comment

by:objects
ID: 8235820
Glad I could help :-)

http://www.objects.com.au/staff/mick
Brainbench MVP for Java 1
http://www.brainbench.com
0
 
LVL 28

Author Comment

by:dpearson
ID: 8235861
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
 
LVL 92

Expert Comment

by:objects
ID: 8235920
> 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
 
LVL 28

Author Comment

by:dpearson
ID: 8236062
> 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

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Suggested Courses
Course of the Month14 days, 20 hours left to enroll

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question