<$BlogRSDUrl$>

Saturday, February 15, 2003

Nasty Webstart Classloader Bug Revisited... 

I blogged about a nasty webstart classloader bug a couple of weeks ago. I found a workaround for the bug at the time, but as it turns out, the the issue would still rear its ugly head under certain circumstances. We set the correct classloader during startup to get around the WebStart classloader bug described earlier. For our application, we have JBoss on the server and a Swing client that's usually run through webstart. All UI events are all dispatched via the AWT-EventQueue thread. Anytime an uncaught exception occurs as a result of one of these events, it would bubble all the way back to the top, and cause this thread to exit. A new AWT-EventQueue thread would then be started, but that new thread again have the wrong classloader (as per the WebStart classloader bug... sigh...). The solution to this problem was this : 1. Created a custom class to handle exceptions (see below). 2. Installed this class as the handler for uncaught AWT-Excpeptions (via the undocumented system property "sun.awt.exception.handler"). The class we used was basically this :
      public class UncaughtAwtExceptionHandler
      {
         public static void installAsUncaughtAwtExceptionHandler()
         {
            System.setProperty("sun.awt.exception.handler", UncaughtAwtExceptionHandler.class.getName() );
         }
         public UncaughtAwtExceptionHandler()
         {
         }
         public void handle (Throwable ex)
         {
            // log the error...
         }
      }
Now anytime an uncaught exception bubbles all the way to the top of the AWT-EventQueue thread, the handle method on UncaughtAwtExceptionHandler is called (and the AWT-EventQueue thread does not exit). The only constraints on one of these classes is that they must have a public, zero argument constructor and a method which matches the handle method signature (void return type, Throwable as the single parameter). I found this property by looking at the source for the AWT class EventDispatchThread (good thing they ship JDK's with the source). There is a comment on a private method which cautions that this property will one day go away when better API support for uncaught exceptions is provided (I believe this is scheduled for JDK 1.5). One other solution I explored while trying to solve this was defining a custom ThreadGroup in the main of the program, and creating a new main thread with the correct ClassLoader. Then I let the original webstart thread "end", while I started up our application in the newly created thread. You can override ThreadGroup's uncaughtException method to get a notification anytime a thread in that ThreadGroup dies (I was going to try to use this hook to send a runnable to the awt event queue via the SwingUtilities.invokeLater method that would reset the classloader in the new thread). Nonetheless, I could never quite get it to work the way I wanted (couldn't get the AWT-EventQueue to belong to my ThreadGroup in a Webstart application). I looked a thte source and it looks like the awt's dispatch thread uses the ThreadGroup and ClassLoader of the first thread that causes it to do anything (and I think WebStart was doing some awt stuff before our program even started). Anyway, it was around that time that I stumbled upon the property above, and I thought that would be a more foolproof solution (keep the event queue thread from dying in the first place). I really hope they fix this bug in the next version of WebStart (I'm suprised they haven't done it already).

Thursday, February 13, 2003

Travel Lightly... 

One of the arguments I really liked from Cockburn’s Agile Software Development book is that the goal of a software project is not to produce good documentation, but rather, to produce good software. Documentation such as UML Models are a means to an end. They serve the purpose of helping to communicate vision, architecture or design. Models are valuable tools for doing this – but the key point is, don’t get so enamored with them that you lose site of the real goal.

Here’s an excerpt from Scott Ambler’s Agile site (http://www.agilemodeling.com/principles.htm) that I thought reiterated the same point :

"Travel Light. Every artifact that you create, and then decide to keep, will need to be maintained over time. If you decide to keep seven models, then whenever a change occurs (a new/updated requirement, a new approach is taken by your team, a new technology is adopted, ...) you will need to consider the impact of that change on all seven models and then act accordingly. If you decide to keep only three models then you clearly have less work to perform to support the same change, making you more agile because you are traveling lighter. Similarly, the more complex/detailed your models are, the more likely it is that any given change will be harder to accomplish (the individual model is "heavier" and is therefore more of a burden to maintain). Every time you decide to keep a model you trade-off agility for the convenience of having that information available to your team in an abstract manner (hence potentially enhancing communication within your team as well as with project stakeholders). Never underestimate the seriousness of this trade-off. Someone trekking across the desert will benefit from a map, a hat, good boots, and a canteen of water they likely won't make it if they burden themselves with hundreds of gallons of water, a pack full of every piece of survival gear imaginable, and a collection of books about the desert. Similarly, a development team that decides to develop and maintain a detailed requirements document, a detailed collection of analysis models, a detailed collection of architectural models, and a detailed collection of design models will quickly discover they are spending the majority of their time updating documents instead of writing source code."


This page is powered by Blogger. Isn't yours?