Today I am thrilled to have the first guest spot blogger on “Pushing Pixels”. Christopher Deckers, the developer of DJ project that brings rich native features to Swing applications, has graciously agreed to post a summary of his findings on using the DISPOSE_ON_CLOSE window close mode in WebStart environment. Note that a similar scenario was reported and fixed on another “rogue” VM thread.
After hours of coding, you finally release your wonderful Swing application. It is using Java 1.4 (or later), it was tested locally and it was terminating properly. You package it and release it as a Webstart application. Unfortunately, you are using setDefaultCloseOperation(DISPOSE_ON_CLOSE) on your JFrames. Soon, users complain that your application remains in memory after they hit the close button of the last frame.To track down this abnormal behavior, you read the AWT threading rules again, detailed in the following file from the javadoc:
“Prior to 1.4, the helper threads were never terminated.Starting with 1.4, the behavior has changed as a result of the fix for 4030718. With the current implementation, AWT terminates all its helper threads allowing the application to exit cleanly when the following three conditions are true:
* There are no displayable AWT or Swing components.
* There are no native events in the native event queue.
* There are no AWT events in java EventQueues.”
It sounds like you are respecting the rules, so something somewhere is misbehaving. The culprit seems to be Webstart.
The JVM should exit, which means there is a non-daemon thread alive in the system:
- The non-daemon thread is a Webstart-related system thread.
- The non-daemon thread is the event queue.
Creating a simple test case (an empty JFrame using DISPOSE_ON_CLOSE), we add a timer to dump all the threads a few seconds after we actually close the application.
Comparing a local run and a Webstart run, we see several additional threads in the latter case:
Javaws Secure Thread (non-daemon)
traceMsgQueueThread (daemon)
Image Fetcher 0 (daemon)
CacheCleanUpThread (daemon)
AWT-EventQueue-1 (non-daemon)
TimerQueue (daemon)
TimerQueue (daemon)
Surprisingly, we can see two UI threads (AWT-EventQueue-1 in addition to AWT-EventQueue-0) and a special Webstart thread named “Javaws Secure Thread“.
A quick test shows that if we forcibly kill the “Javaws Secure Thread” (using the not-so-recommended call to Thread.stop()), then closing the application succeeds.
This behavior leads to two conclusions: this Webstart thread is a non-daemon thread so the JVM cannot exit, and it also seems to post new events to the UI thread that restarts it.
Time to hunt for the code of the “Javaws Secure Thread“!
A quick search in jre\lib\javaws.jar and we can find its declaration: a class named SecureThread, nested in the com.sun.javaws.ui.JavawsSysRun class (the code can be found in deploy\src\javaws\share\classes\com\sun\javaws\ui folder of the JDK source distribution).
The code after simplification is roughly equivalent to the following:
class SecureThread extends Thread {
public void run() {
while(true) {
doWork();
}
}
public void doWork() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// stuff
}
}
// other stuff
}
}
All seems confirmed: Webstart does create a non-daemon thread, which continuously posts events to the UI thread.
The solution? Well, like back in the 1.3 days, use EXIT_ON_CLOSE on the main frame (if any) until this eventually gets fixed in webstart.
Here are some Swing links that you might have missed during this week:
- Alex Ruiz writes about the release 0.8 of FEST-Swing library for functional Swing GUI testing. It features a considerable number of new functionality and seems to be progressing smoothly towards the first production-ready release.
- Andres Almiray writes about release 0.4.4 of GraphicsBuilder, bringing a variety of new features from Swing to Groovy.
- Dave Gilbert writes about release 1.0.9 of the JFreeChart chart library, mainly featuring bug fixes and small API improvements. I wonder what happened to the 3D support that has been announced last July. Is there a big demand for 3D charts? Is it worth the development effort?
- Peter Weishapl writes about updates to the xswingx project that brings advanced capabilities to text fields, including prompts, buddy icons and search fields.
- Jeremy Wood (java.net nick mickleness) has an interesting project on java.net for slideshow transitions. It features an impressive array of very smooth and rich transitions that can be employed in slideshow components.
- Sun’s marketing machine seems to pick up the steam on the application framework and beans binding projects (even though the technical leads seem to be currently devoting their resources to the JavaFX related activities). Tech Day Events blog has a short overview of these two projects, while Frank Sommers interviews Shannon Hickey on the beans binding at Artima.
- And speaking of the main technical lead for the application framework JSR, Hans Muller kicks off the series on the new Scene Graph project, showing a few very basic capabilities. Chet Haase writes about the next evolution of the Timing Framework that is undergoing very significant changes for its inclusion in Scene Graph (and probably JavaFX / Mustang Update N). The first part talks about the API changes, and the second part introduces the new functionality.
- Tom Schindl writes about the first version of the UFacekit project that aims to bring a common layer on top of different UI toolkits, including GWT, SWT / JFace and Swing. This is a commendable effort, and it would be very interesting to see how the authors (Tom and James Strachan) are going to tackle the functionality missing in some of the UI toolkits. Would that be the least common denominator, optional extensions (with querying the toolkit capability), emulation of missing features or something else? Definitely worth tracking.
Following the last few entries on using SWT for native text rendering in Swing applications under the Substance look-and-feel, i was contacted by Steve Northover (technical lead of the SWT project) with a few suggestions. First, to recap the relevant entries up until now:
- The introduction showed a few screenshots of rasterizing the default Vista Segoe UI font in Swing and SWT.
- The next entry showed some of the implementation details of the interaction between the two UI toolkits.
- The “ready, steady, go” announced the official stable plugin version, along with much simpler deployment, support for WebStart environment and more.
- The last entry showed some quirks of rendering vertical texts.
Steve’s first suggestion was to go over the code and make sure that all SWT resources are properly disposed. While this has been considered as one of SWT’s weaker points (something along the lines of “it’s Java, why do i need to explicitly dispose resources”), this is hardly any different from Graphics2D.dispose or even explicitly closing DB connections, streams, files etc in usual Java programs.
If you don’t call the dispose() method of all allocated SWT resources, you can run into the “No more handles” error. While usually it takes quite a while to get there, the native text rasterizer would encounter it fairly quickly (about 5-6 resources are allocated for each text painting in the current implementation). While the text rasterizer itself is disposing all its resources, the test applications did not. This has now been fixed.
The second suggestion was to strip away unnecessary classes from the SWT jar. While this jar is by no means huge (clocking in at about 1.3MB), some people would cringe at this figure. First, i would like to enumerate the reasons why i don’t recommend stripping away the contents of swt.jar (as detailed below):
- While the license permits it (and the whole plugin is under EPL), i’m rarely comfortable in stripping away contents of third-party libraries. When i upgrade to the latest release, i can eliminate at least one possible source of incorrect behavior (if something weird happens).
- The swt.jar for Windows has quite an acceptable size for the functionality that it provides. For example, the main Substance look-and-feel jar is about 1.7MB.
- An application that decides to use this plugin might as well “profit” from other parts of SWT, as illustrated by Chris Deckers’ posting on Javalobby. This way, the two libraries can share the same swt.jar.
Having said that, it is possible to strip the swt.jar to as little as 430KB. There are two ways to do so – the approach recommended by Steve, and the aggressive approach that resulted in the current swt-win-stripped.jar available from the CVS repository.
The recommended approach is to work on the package level, removing those packages that clearly are not required for the text rendering. The minimum set according to Steve is org.eclipse.swt.graphics, org.eclipse.swt.widgets, org.eclipse.swt.internal, org.eclipse.swt.internal.win32 and org.eclipse.swt.internal.gdip (for GDI+ operations such as tranformations for the vertical texts). In addition, the swt-win32 and swt-win32-gdip DLLs (for Windows) need to be in the stripped jar. Furthermore, Steve mentions that the org.eclipse.swt.events and org.eclipse.swt.accessibility might be needed for corner-case scenarios, such as switching the OS theme while the program is running (correction from Steve – these are needed to compile a stripped SWT jar from sources).
However, you can take it a little bit further and remove additional classes from the org.eclipse.swt.widgets (pretty much everything that concerns actual components, since these are not needed for the text painting and image manipulation for this plugin). Take a look at the contents of this package in swt-win-stripped.jar in the CVS or the distribution zip to see what has been left. This is what brings the jar size down to 430KB.
As an “extreme” measure, one can go even further and start stripping unnecessary functionality from the DLLs, org.eclipse.swt.SWT class and org.eclipse.swt.internal.win32.OS class. Do at your own risk.
Note that while this entry talks about the Windows version of SWT, the same applies to other platforms as well (which would have a different structure of org.eclipse.swt.internal package and different bundled native libraries).
I’d like to thank Steve Northover for his comments and time.
Here are some Swing links that you might have missed during this week:
- Luan O’Carroll writes about updates to the rollup bar component from the XUI framework. The functionality of the component seems to lie somewhere between the task pane container / collapsible panels of SwingX and the collapsed panels of docking frameworks. The links to the demo videos seem to be down, and it would be interesting to see a WebStart demo and learn how well the component integrates with core and third-party look-and-feels.
- Andres Almiray continues his work on the GraphicsBuilder for Groovy. This week he talks about advanced strokes (based on the code by Jerry Huxtable) and the wide variety of geometrical shapes.
- John Zukowski provides a simple overview of placing custom components on tabbed panes (available starting from JDK 6.0). Unfortunately, all the tutorials i have seen on the subject deal exclusively with putting close buttons on tabs. I would be very interested to hear about at least one another valid scenario for using custom components on tabs. If there is none – why this functionality hasn’t been restricted to, well, putting only close buttons?
- Angelo De Caro writes about release 1.4.0 of MyDoggy docking framework.
- software4java company announced availability of the adaptive menu component. The functionality of adaptive menus introduced in the Microsoft Office 2000 to Swing application has a few significant shortcomings addressed at length in this posting by the lead designer of Office 2007, Jensen Harris. While it is still available in Office 2007, it is turned off by default – if you’re thinking about including this functionality in your applications, you might want to reconsider it.
- Christopher Deckers makes quite an unexpected announcement on library that brings integration with an impressive collection of native components to Swing applications. Based on SWT (with the applying restrictions of target platforms and bundled native libraries), it already provides solutions for embedding web browser, Flash player and multi media player, as well as querying the native file associations and launching registered applications (which looks very much like the Desktop class introduced in JDK 6.0).