Alex headshot

AlBlue’s Blog

Macs, Modularity and More

When Java just doesn't Swing

2005, java, swing, swt

Josh recently asked Why don't you ship Swing apps?. There's a lot of Java-based applications out there (and more of them are starting to be based on the Eclipse Rich Client Platform) and some of them look really nice; for example, the Azureus BitTorrent client. And then you find out that they are all based on the SWT, and not Swing.

The reason that Swing has fallen out of favour is that it doesn't evolve fast enough. SWT has been evolving as part of the Eclipse platform for some time now, and has gone through several version changes. Here's how they looked:

Date Release
 * For Eclipse 1.0 and 2.0, SWT was not a separately downloadable component
November 2001Eclipse 1.0 *
June 2002Eclipse 2.0 *
March 2003Eclipse 2.1 and SWT 2.1
June 2004Eclipse 3.0 and SWT 3.0
June 2005?Eclipse 3.1 and SWT 3.1

Now compare this with Java releases:

November 1996Java 1.0 (AWT)
August 1997Java 1.1 (AWT)
December 1998Java 1.2 and Swing
May 2000Java 1.3 and Swing
February 2002Java 1.4 and Swing
September 2004Java 1.5 and Swing

The difference is that an Eclipse major milestone release is (a) probably a significantly larger codebase, and (b) about 50% shorter release cycle than the equivalent Java base is updated. As such, wedding the UI to the core Java causes problems in updating the UI. For example, in the early days, in order to run server-side Java on AS/400s and other green-screen systems (mainframes), IBM had to invent a VNC-type solution to be able to pretend to run AWT components, just so they could pass the test kit. Note to anyone inventing the Next Big Language: don't wed yourself down to components and the base language; let them evolve independently.

I've gone on about the difference between SWT and AWT before, so I won't repeat any of it here. But even more than that, the problems with Java GUIs are more than just the UI toolkit; you've got to have a VM installed.

Now, if you're one of the lucky ones reading this who are using Mac OS X, good on you. You know that you're running a version of Java, built into the operating system, but for other less fortunate operating systems, you've got to get Java in the first place. That's a big download; between 40 and 50 Mb depending on your platform.

What's worse is that the update mechanism is diabolical; like other Sun products, they view the 'network as the computer' and so don't mind paying large amounts of money to use it. (Are they co-owned by Cisco?) But if you're on a slow dial-up connection, or are using metered bandwidth (Wake up America! Metered bandwith exists outside your country) then downloading a big file isn't that practical. What's worse, the update mechanism seems to download the entire thing again, instead of being intelligent and downloading just the changes. (Software Update on Mac OS X now does exactly that; when it finds an update, you can download a Delta update, which is just the fixed files.) Would you believe that in order to download new recommended updates from Sun for Solaris, you have to download the entire set of fixes as a ZIP or a CD image, even if you've already got one? And then, when it installs the patches, it runs through every patchset *again*, this time complaining with error code 8 (already installed)?

Their versioning numbers are almost laughable too. Whilst the major numbers outlined about (1.1, 1.2, 1.3 etc.) are a good idea of what version you are using, there's a minor one. It started sensibly enough with 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, 1.1.2, 1.1.3 etc. up to 1.1.8. But Sun eventually got embarrassed with the fact they took 8 attempts to get something right, and changed their strategy to have underscores on the end. Here's a complete list of the versions you could download for Java:

Java 1.0
1.0.0, 1.0.1, 1.0.2
Java 1.1
1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7, 1.1.8
J2SE 1.2 formerly known as Java 1.2
1.2.0, 1.2.1_004, 1.2.2_004, 1.2.2_005, 1.2.2_006, 1.2.2_007, 1.2.2_008, 1.2.2_009, 1.2.2_010, 1.2.2_011, 1.2.2_012, 1.2.2_013, 1.2.2_014, 1.2.2_015, 1.2.2_016, 1.2.2_017
J2SE 1.3 formerly known as Java 1.3
1.3.1_14, 1.3.1_13, 1.3.1_12, 1.3.1_11, 1.3.1_10, 1.3.1_09, 1.3.1_08, 1.3.1_07, 1.3.1_06, 1.3.1_05, 1.3.1_04, 1.3.1_03, 1.3.1_02, 1.3.1_01a, 1.3.1_01, 1.3.1, 1.3.0_05, 1.3.0_04, 1.3.0_03, 1.3.0_02, 1.3.0_01, 1.3.0
J2SE 1.4 formerly known as Java 1.4
1.4.2_07, 1.4.2_06, 1.4.2_05, 1.4.2_04, 1.4.2_03, 1.4.2_02, 1.4.2_01, 1.4.2, 1.4.1_07, 1.4.1_06, 1.4.1_05, 1.4.1_04, 1.4.1_03, 1.4.1_02, 1.4.1_01, 1.4.1 , 1.4.0_04 , 1.4.0_03, 1.4.0_02, 1.4.0_01, 1.4.0
J5SE 5.0 1.5 formerly known as J2SE 1.5 formerly known as Java 1.5
5.0, 5.0_01

(If you are still confused about naming, Sun posts a helpful document about it J2SE 5.0 Name and Version Change)

Now imagine that you've had auto-update, or you are someone who downloads a new VM whenever it is out. Assuming you got on the 1.2 bandwaggon rather than before, there have been 18 (1.2) + 22 (1.3) + 21 (1.4) = 61 releases of Java since 1.2 was released. Assuming an average download size of 30Mb, that's about 1.8Gb worth of data, or 4 DVDs worth of information. Realistically, the updates can't have changed every class every time, and if there had been an intelligent update mechanism in place from the start, it might have been practical to keep up to date with Java. (Even the current updater is broken; I'm running Java 1.4 at work, and it tries to persuade me that an update is available; despite the update being for 1.5.) Even more foolishly, each install tries to put itself in different directories, with the result that you end up wtih paths like c:\j2sdk1.4.1_02. What this means is that every time you do an update, you've got to change your JAVA_HOME variable and paths to point somewhere else. Unless, that is, you're intelligent enough to realise that if you install it into C:\Java\J2SE_1-4 then each time an update runs, you can put it in the same place (after backing up the previous directory, of course).

And, just in case Java wasn't taking enough space up for you, when you install it on Windows, it installs a second copy in a JRE directory (with, of course, the same stupid naming conventions). So you can develop and test with a JAR in your lib/ext directory, but when you try and run it in the browser, it fails because it's using a different VM. I mean really -- why do you need two copies of the damn thing installed?

So the conclusion is; there's nothing specifically against Swing that is causing the problem about adoption of Java Swing apps. The problem is that Java on the client side still sucks, and although technologies like Java WebStart help, the problem is that the Sun VM is packaged and updated in probably the worst possible way. No wonder vendors like IBM produce their own VM, and even then only release it as part of a mainstream product when it's had time to go through the 20+ service packs.

I personally think that Eclipse RCP applications will take the lead, because it's a framework for building apps. Creating a subclass of JFrame is never going to be a sensible way of building reusable application components; one of the reasons that there are far more Mac OS X applications than Java applications (and let's face it, Java's been around longer than Mac OS X has, if you excuse its NeXT heritage) is that Mac OS X has always had a good set of frameworks for building applications. As an example; if you want to enable drag-and-drop in your application, you simply tell the component what type of data it knows about. The framework handles the rest. In Swing, you've got to register the listener, register the drop area, provide the hooks for detecting when a drag is started (or cancelled) and do everything at the lowest possible level, even to the extent of animating the icon of what you're dragging under the mouse. With the Mac's frameworks, It Just Works.

I think that a new language will become the new Java in the next five years, and that that language will be an open-source implementation (though probably hosted from somewhere like Eclipse or Apache). When Eclipse is re-written to use that language, Java will be officially dead. Furthermore, this language will have a separate VM download from core component libraries, in much the same way that Eclipse uses plugins to activate its code, and these plugins will be easily obtainable and downloadable without having to agree to proprietary closed licenses. Nor will people complain if they put up the documentation at useful sites like JDocs citing copyright infringement.

In short, Java is dying along with Sun. They're even trying desparately to make people download NetBeans as part of a Java runtime environment, rather than selling it on its own merits. And frankly, the reason why Sun claims so many downloads of Java is because there have been so many patches downloaded by so many people ...