The Benefits Of Open Sourcing Java For Developers

May 11th, 2007

There was an interesting panel discussion at JavaOne today about the open sourcing of Java. The panel was made up of folks developing open source JVMs and a representative from Sun. Compatibility is obviously a common theme to these discussions and there were a number of mentions to just how bug for bug compatible the alternative JVMs are trying to be. It occurs to me though that if all the implementations wind up behaving in precisely the same way, there's not really any point to having multiple implementations. Yes multiple licenses are nice for particular niches but for the average Java developer, what's the benefit?

A reporter came up to me after the session (apparently I'd made some good comments) and asked about what benefits I saw. Her first question was about how useful having the source code would be. The trouble is, the source code for the standard Java class library has been available for as long as I can remember and open sourcing Java doesn't change the legality of copying and pasting code (unless your product is GPL) so there's no real advantage in source access. There are a few sun.* classes that now have source code available and didn't previously which can be useful but not overly so.

The other advantage is that was mentioned by the panel is that you can fix bugs for clients *now* instead of having to wait for the next release of Java. Of course, for the average developer this isn't really an option either because it would involve deploying the fixed JVM to all their customers. It might be feasible for people running controlled servers that just run their apps but it's unlikely to be practical very often. You could however add a workaround to your application for now and contribute a fix back to the JDK for the future which is likely to happen a fair bit.

One interesting aspect of contributing fixes back is that in a lot of ways, there is an incentive for companies not to contribute the fix back - they now have one less bug than their competitors. If the fix requires significant maintenance contributing it back is a pretty clear win, but many work arounds don't have any real need for maintenance. They might be in areas of code that are very infrequently changed, they might be modular enough to be quite separate etc.  Ephox products have a lot of work around for bugs in various browsers, JREs and OSs, many of which receive so little attention and maintenance that we can be surprised to find them years later, still working perfectly and still working around an unfixed bug (we do report these to Sun, but few people run into them so they tend to be low priority). The other consideration is that even if future versions of the JRE include the fix, you still can't remove the work around because the older JVMs are still in use by various clients, so you pay the maintenance price anyway.

There are other business considerations involved with the decision to contribute to the JDK as well - you have to sign the copyright on the code over to Sun which can be a sticking point with a lot of companies. After all, why should Sun get to sell the code that you paid to have developed? (And Sun does still sell the code, they have a bunch of different licenses for the Java code including commercial ones, not just the GPL). You also have to go to the expense of reviewing the various legal agreements for contributors and going through the patch review process etc. It's not just a simple matter of putting the patch on your blog and it being magically part of the JDK.

It will be really important for the OpenJDK team to work hard to limit these barriers to contribution if they want to attract contributions. I'm certain it's something that they're already thinking about, but how it pans out with the lawyers will be interesting to see.

The other potential benefit that an open source JVM may provide is the ability to port it to other OSs and architectures. People are already suggesting that this will mean OS X will always have up to date Java just by recompiling. Unfortunately, it's just not that simple, you first have to port the JITC to output PPC code instead of x86 which is a huge job, then you have to rewrite the AWT toolkit implementation to work with Quartz. Then you have to write a plugin that works with OS X browsers and deal with all the Cocoa vs Java threading issues. Then you have a working JVM, but still no native L&F, no tie ins to the OS (Apple provide some reasonably simple but very powerful features like being able to put the menubar at the top of the screen and handle dropping files onto the application etc). It's good that it's possible to port, but it won't happen soon and it won't be easy. Judging by the number of Apple laptops here at JavaOne there may just be enough interest to get it done though. BSD is also a likely candidate for a porting project and that should be a lot simpler.

Beyond that, Java developers aren't going to see much difference except possibly that they have to stop making assumptions that if it works with Sun's JRE it will work anywhere. Of course, that's never been true anyway, particularly from a performance perspective, as people who have brought apps over to OS X have found out. It's a huge change for the Java community, but one that only a very, very small subset of the community is going to be affected by.

Extreme GUI Makeover

May 11th, 2007

The session was a lot more fluff than useful stuff and often went for showy graphics instead of actual usability which is a shame. There were some good ideas though.

  • Use a modern L&F - they suggested Nimbus. Gosh it's ugly and gray. I suggest using the system native L&F (except on Linux and Solaris then anything is an improvement)
  • Add a splash screen, can do this with the -splash argument in Java 6.

    • Supports alpha transparency so can be non-rectangular
    • Should provide a progress bar.

      • They used a sepia image fading into color to show progress which looked cool but didn't really show progress at all effectively.
  • Validating Data

    • Give feedback immediately.
    • JGoodies can provide a small icon in the corner of the component. You can do this yourself by painting the icon in the layered pane's popup layer.
  • Custom Components

    • You can improve GUIs by creating custom components.
    • This is where they messed up usability in some places. Make sure your custom components are significantly easier to use than the standard components otherwise it's better to go with what the user is used to. Also need to consider accessibility which they didn't mention at all.
  • Improve interactivity by updating search results immediately as the user changes values.
  • Use cyclic gradients for improved performance, even if you don't need the cyclic property (just paint one iteration).
  • Measure text with:

    • g2.getFotnMetrics() then stringWidth and getAscent
  • JList has a setLayoutOrientation method which lets you use it as a multicolumn list.
  • You can span text across all the cells in a row by clipping the text with a JViewPort to show just the section inside the cell currently being painted.
  • You can animate the changes made when sorting by painting the animation in the glass pane over where the table is.

Being Productive With Swing

May 11th, 2007

These are my notes from the technical session, "Being Productive With Swing" by Ben Galbraith. The session focussed a lot on Ben's library that he's creating which was a shame but there are some ideas that are worth taking away.


The techniques described below are very specific to business applications that center around forms. At the moment desktop applications are "stepping up the wow" to compete with AJAX and Swing traditionally hasn't had this - JavaFX is likely to bring this to Swing. However, for most business applications "wow" isn't a requirement, productivity is. In that area, no emerging platform provides material advantages over Swing with the exception of JFace and Cocoa.

JFace has some really nice abstractions which make it productive, but is hard to learn.

Cocoa has great data binding via Core Data and excellent tooling support which makes it very productive, but it's Mac only.

For business application development, productivity is king. How quick is it to make, how easy to reuse, how cheap to maintain? Swing's not too far from being productive but isn't there yet. JSR296 (swing application framework) doesn't help with productivity much because it's really just targeted at getting started with an app, not the actual form design. JSR295 Beans Binding is a key improvement.

What's missing from Swing? It needs to be a framework instead of just a GUI toolkit. What's a form? How does validation work etc .

Template Pattern

There are too many ways to create a GUI which makes understanding and reuse difficult. He's created a system to enforce a standard template. The aim is to split the code up and provide as many behavioral contracts as possible to enable reuse. (To me it looks like too much up front engineering - most of the time you don't want to reuse GUIs, they're task specific so what's the point of designing every GUI for reuse?)

GUI Builders

GUIs used to be hand coded because tools weren't good enough. Ben suggests that modern GUI tools have solved that problem and there's no good reason to use a GUI builder and he believes he's vastly more productive using a GUI builder. Often though, people aren't happy about having machine generated code that they then have to maintain. The key is to keep the machine generated code completely separate:

  • Bind behaviors to components by name
  • Let the builder own all the code it develops
  • Supplement the GUI builder at runtime as needed by manually creating just the parts that are dynamic.
  • Use an abstract GUI builder plugin system.

    • Support any GUI builder
    • Support custom frameworks.

Ben then went into a particular function he's developed that helps retrieve a component by name easily. Basic idea was taken from prototype.

The issues I see with this that Ben didn't address:

  • How do you change GUI builders and preserve the work you've done? What if the GUI builder you currently use is discontinued?
  • Ben suggests you can work with a team that uses a range of different GUI builders and it'll still work. Sounds like a nightmare to me.
  • What do you do if you don't have access to the GUI builder that was used? How do you maintain the code?

Binding

JSR295 is very exciting. Binding is important to avoid all the code required to copy data between the GUI and the model. This code is often error prone and duplicated, particularly when parsing is required (ints, dates etc)

Opensource binding systems have been available for a while and JSR295 won't be available for some time.

The problem with binding in Java is that most systems try to make the binding bi-directional (automatically respond to changes made in either the GUI or the model). Java doesn't have a way to watch a variable for changes so you have to implement property change notifications which is tedious and error prone. While AOP could be used here, it's not widely accepted and you can't assume that you can just store the current value, make the change and send the notification - some variables need special change handling.

In most apps, there isn't a need for bidirectional binding, it's okay to just provide a method that tells the binding framework when changes have been made to the model (swing already has property change notifications built in so it can use them).

Simple Configuration

It's a pain to apply common attributes like padding, bolding etc to components. Ben implemented CSS for Swing to work around this. To me CSS doesn't apply particularly well to Swing - it's a DSL for styling HTML, not swing. It would be better to create a DSL specifically for styling swing if you wanted to go that route, but if you're using a GUI builder you should just use the GUI builder to do this so that it owns all the code and you can see what it actually looks like in the GUI builder. Otherwise, write the GUI by hand and just use utility functions to set up components with the default settings you need.

Ben's framework is available from http://code.google.com/p/swing-clarity/

JSR296 Swing Application Framework

May 10th, 2007

These are my notes from the talk on the Swing Application Framework (JSR296). This is probably my favorite technology I've seen at JavaOne so far. It's not trying to be overly fancy but it solves a clear need in a very simple way.

Malcolm Davis also commented on it but wasn't impressed. Personally I think he missed the point. Firstly Malcolm, yes Eclipse and NetBeans platforms have had basically all these features and far, far more for a while and that's the problem. Using Eclipse or NetBeans as a base for a small or medium sized swing app is total overkill and the frameworks are huge and take ages to learn and configure for your needs. JSR296 is all about defining a really simple framework that gives you just the basics. If you need more you can either add on to it or go the whole hog with Eclipse or NetBeans. Malcolm suggested a few areas he thought it should also cover:

  • Help
  • Preference Screen
  • Update

The thing is, all these three things are really simple to plug in as separate modules. There's no need to bundle them into every single application because not all apps provide or need help, preferences or automatic updates. Also, Help is already provided (poorly) by JavaHelp and updates are already handled by Java WebStart. So all we really need is a Swing based preferences library (that hopefully looks nothing like the Eclipse preferences which are pretty awful).

Anyway, the notes I took are below.


From the very first release of swing, people have been asking for a framework to make writing Swing applications easier. It's finally happening.
JSR295 beans binding is also a part of the solution in that it simplifies the wiring together of the application logic and the GUI.
The swing application framework is intended to be a very lightweight framework for small to medium applications. It has no module system, GUI markup, docking etc. It should be as simple as possible and no simpler. The NetBeans and Eclipse frameworks provide these things and may be more suitable for large applications but are too big for small applications.

Key aspects of the swing application framework:

  • Life Cycle
  • Resource Management
  • Actions 
  • Tasks (for asynchronous work in background threads)
  • Session State

The framework is centered around two singletons, Application and ApplicationContext. They function in a similar manner to Applet and AppletContext. To use the framework, you create a subclass of Application and implement the startup method. Then, in the main method, call Application.launch. You use the ApplicationContext class to register tasks, retrieve resources etc. For applications that only use a single frame, the SingleFrameApplication provides some extra functionality like exiting when the frame is closed.

Life Cycle

The Application class defines the lifecycle of the application. You can control aspects of the life cycle by overriding on of the methods in Application: launch, init, startup, ready, exit, shutdown. You can also use exitListeners to veto the shutdown if needed (eg: prompting the user to save). It looks like most of the methods are called on the event dispatch thread but check the JavaDoc to be sure.

Resource Management

Resources are designed with the existing ResourceBundle system. There are some utilities to make the more useful, for example the ability to easily store and retrieve Colors and other resources. Locale specific bundles can be used as normal, but also platform specific bundles.

ResourceMaps are the interface to the resources and are just like a normal Map but include parent chaining. They also support string to type conversion (eg: Color) and the conversions supported are extensible.
The resources go in a resources subpackage. Eg: com.myapp.MyApplication has resources in com.myapp.resources

The framework can also handle resource injection by applying resources to components with a specified name. You can also use the @Resource annotation to have resources injected into a component stored in a class field. The name looked up in the resources is then the same as the name of the variable. So if there's a button called "myButton" it's resources would look like:
myButton.text=Foo

Advantages of resource injection:

  • Localization happens by default
  • No need to explicitly set resources - saves a lot of code.
  • All GUI resources are stored in one place instead of scattered throughout the java code.

It's not meant to be a styles mechanism or general GUI markup just a simple way to specify properties to set.
Note that injecting private fields with the @Resource annotation requires privileges (which it will have once this becomes part of the JRE).

Actions

The actions used are the standard Swing Actions. However they suffer from a few problems:

  • Not localized
  • Creating them is a pain.
  • Asynchronous work is hard.

To solve this, there is a new @Action annotation. You mark a method with it and an action is automatically created that calls the method on actionPerformed. You can retrieve the action with the getAction method on ApplicationContext. For example:

@Action public void doStuff(ActionEvent e) {}

The ActionEvent argument is now optional and there are ways to specify what arguments are passed through to the method. The resource management system then injects the localized resources into the action based on it's name.

You can also bind the action's enabled state to a variable:

@Action(enabledProperty = "changesPending") public void doStuff() {}

the action will then enable and disable whenever the changesPending variable is changed (through beans binding).
Actions have problems when used in toolbar buttons and menu items - the menu items need text, the toolbars shouldn't have it. You can achieve this by overriding the text for the action in the toolbar button by specifying toolbarButtonName.text=${null}

Tasks

Tasks are a simple mechanism to avoid blocking the event dispatch thread by spawning background threads. When using these background threads though, you need some way to manage them - display progress, start, stop and send messages.
SwingWorker already does most of this but Tasks takes it a step further.
Tasks use the Java concurrency library so it's Java 1.5 only (probably possible to backport to 1.4)
The first enhancement to SwingWorker is the addition of multiple "done" type methods that handle different ways that the task completed - cancelled, error or successful completion. This is error prone with SwingWorker.
Tasks also provide a means to block the GUI without freezing it by displaying a modal progress dialog. Use the block and unblock methods to use it. There are also a series of properties to control the scope of blocking.

For managing the tasks, there is a TaskService which can be configured to execute tasks serially, in parallel with thread pools etc. It's possible to create multiple task service instances for different types of operations (network, database etc). You can specify this via the Action annotation:

@Action(taskService="database")

The ApplicationContext provides access to the instances of TaskServices.

Finally, there's a TaskMonitor class that provides a summary of the running tasks which is good for status bar implementations.

Session State

Very simple. It stores which windows are where on screen and JTable column sizings so they can be restored to those locations when the application is restarted. Most apps don't manage this themselves because they either don't know where to store the state, are unsigned and can't store it or they don't have a way to safely restore the state. The storage is available via the ApplicationContext.getSessionStorage method.

Desktop Java

May 9th, 2007

Just finished up in the Desktop Java overview session. Good information in there. The summary glosses over some stuff but I think it covers all the important information. The entire session is an overview so it's really just identifying things that you should look to learn about elsewhere. It looks like some good stuff for Ephox and our user is coming down the pipeline.

Main points:

  • Java on the desktop used to be focussed at the enterprise desktop, now it will focus on becoming far more consumer oriented.
  • JavaFX is cool.
  • Java 6 Update in 1st half of 2008 to include:

    • JRE Detection improvements (funky scripts to get the right JRE installed, seems to bounce off sun.com)
    • Install process improvements (Kernel)

      • Installs just the absolute minimum components of the JRE and then downloads most common components in the background. Installs less used components on demand. Could be great, but could also cause interruptions to users as they work when new components are needed.
    • Quick Starter. Loads Java files into the disk cache at startup or browser startup and tries to keep them there. Not a full JRE running but will probably be as annoying as all those other task bar icons that are wasting resources trying to do the same thing. No wonder computers take so long to load these days.
    • Windows Graphics Acceleration

      • DirectX 9 based pipeline.
      • On by default so actually useful unlike the OpenGL pipeline which is off because of some driver incompatibilities.
      • High performance for all of Swing and Graphics2D.
      • Nimbus. New cross platform look and feel that's meant to actually look good. Screen shots look pretty awful (gray is not a good choice of color scheme people!)
  • Looking at media improvements in the future.

    • Looks like they want to use native libraries (QuickTime, Windows Media etc) instead of a Java based solution. Seems to be a common trend so hopefully they'll get it working seamlessly.
  • Animation improvements

    • Easy to apply animations and effects.
    • Better timing facilities
  • More components

    • Date picker.
    • Native file chooser
    • Ability to mix heavyweight and lightweight components.
    • Non-rectangular top level components
    • Translucent windows
  • Applications framework

    • JSR 296
    • Makes it easier to get standalone Swing apps started.
    • Basically just removing boiler plate code, but I suspect it includes more than was shown in the talk.
    • Much, much simpler than something like the NetBeans or Eclipse platforms.
    • Intended to be useful for small to medium size apps instead of the huge apps that NetBeans/Eclipse platforms are good for.
  • Beans Binding (JSR 295)