New Open Source SwingCommand library released

September 29th, 2008 Nick Posted in java, swing | No Comments »

I finally completed open sourcing SwingCommand - an open source library which provides support for the command pattern in Swing. In addition to synchronous commands, it provides support for asynchronous commands, which hides away the gory threading details in a similar way to the SwingWorker class - but in SwingCommand the asynchronous commands are integrated into the overall framework, and there are a few extra features, such as composite command support and command execution observers, which I hope make it more flexible.

Reusable Commands

One other key difference from SwingWorker is that in SwingCommand each command instance is reusable (a command can be executed more than once). Each time you call myCommand.execute() a ‘CommandExecution’ instance, which encapsulates the state for that execution. In the SwingWorker provided as part of jdk 1.6, each SwingWorker instance is designed to be executed only once. In SwingCommand there is nothing to stop you creating a new Command instance each time if you prefer, but you also have the flexibility to create a shared Command instance up front, pass references to it around your application and execute it many times if necessary.

Why a new Command library?

There is nothing fundamentally new about using the command pattern in Swing apps, but arguably there is a need for a reusable library to address this problem in a focused manner, and provide a richer set of features than SwingWorker, without attempting to solve every other ui programming issue along the way. SwingCommand has certainly been a useful library in my projects already. It does hide away a lot of the more complex threading issues, typically produces ‘clean code’, and make it easy to build a Swing application around chunks of reusable logic wrapped as Command classes. Integration with java.util.concurrent framework makes it really easy to handle threading issues which would otherwise be complex (e.g to prevent two instances of the same asynchronous command from running simulatenously would be a one line change, by using Executors.newSingleThreadExecutor()).

A milestone

This is the first of Object Definitions’ libraries which I have open sourced. It is fair to say it has been more work than I anticipated to get it to this stage - so it is probably time to crack open a bottle of something fizzy. Once I have recovered from the hangover I’ll post more about it here. In the meantime there is a lot more information on the website and you can download swingcommand library here

AddThis Social Bookmark Button

Getting the NSLU2 to work with vista (why is vista configuration such a mess?)

September 24th, 2008 Nick Posted in hardware, rants and opinions | No Comments »

I just switched to using a Linksys NSLU2 NAS server for my home network.
It’s a great little thing - you just connect USB drives to it and set up network shares using the nifty web administration utitlity.

None of this is new - the NSLU2 (or ’slug’, as they are known) has been around for years now, and there is a cottage industry of linux kernal hackers grown around it, to adapt it to do such things as streaming music etc.

What is new, however, is that it won’t work from Vista. Works like a breeze from XP.

The linksys requires LM authentication which was supported by default by XP, but apparently it is disabled by default in vista, which only supports NTLM out of the box. I suspect this is not Linksys’ fault. The upshot of this is that from your spanking new Vista laptop you won’t be able to log in to your home network devices any more. You’ll probably forget they’re even there. The only person who will be able to log into them will be the guy parked up in a van outside who’s hacking into your wireless network using Windows XP. How’s that for security?

The forums are riddled with messages complaining about this, for the linksys and other similar NAS devices.
Most of them refer to now defunct Vista system administration tools
Searching the Vista help gets you nowhere.

Eventually I found a post which contained a registry setting to edit, to enable LM authentication
A registry setting to edit? Whooo, lucky me.
Welcome to the wonderful world of Windows usability.
If there is a utility which allows you to set this, I’d love to know, Windows admin dialogs are a joy.
I suspect I might be still looking at Christmas given how intuitive the admin is in Vista.

Anyhow, the magic LmCompatibilityLevel registry setting can be changed to let you log in to your network devices:

Note, changing this won’t make your network more secure. However, for your home network it should be OK, provided you’ve secured your wireless network. Any self respecting burgler walking into your appartment probably won’t be spending too much time trying to hack your network passwords. They’ll simply pick up your NAS drive and stick it under their shirt while pretending to read the gas meter, and make off with any win XP laptops (although they may leave your vista machine where it is)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA\

Change the key LmCompatibilityLevel from "3" to "1".

You can edit the registry using the regedit utility
Have fun!

AddThis Social Bookmark Button

Shots in the dark

August 6th, 2008 Nick Posted in random | No Comments »

most pictures with alt=’wharf’ you see on technical blogs are probably star-trek related.
If it’s taking a while to load, I can assure you, no klingons here, especially no mis-spelled ones:

wharf

bridge

If I post any more I’ll start thinking I’m Romain Guy

AddThis Social Bookmark Button

WinSplit Revolution - awesome - just, awesome.

July 10th, 2008 Nick Posted in hardware | No Comments »

I’ve been looking for a screen splitting program for quite a while but somehow this one passed my by.

There isn’t much point in the 4 million pixels in the HP LP3065 unless you can easily arrange windows on the screen. Typically when working I need to run 15 to 20 apps, and view several simultaneously - and its a real waste of pixels if you can only maximise one window.

For a while, I was forced to go back to two screen setup, with smaller monitors, just so that I could easily maximise two apps.
But now that 30 inch monster is back on my desk, ooooh yea, with WinSplit revolution will never be separated again.

It’s a great little app which gives you hotkeys you can use to reposition windows in the screen either left or right, top or botton, in the corners or maximised. You can also use it to move windows between screens. That’s just the beginning - there are plenty of other great features too. So much so that I even find it useful on the 1280×1024 monitors at work. And, did I mention, it’s free? Forget windows power toys - this has instantly become my number one favorite windows utility.

Of course the real irony is that a free utility like this can provide such a huge improvement to the ‘windows’ os, which, despite costing hundreds of dollars, doesn’t even seem to offer the basic minimum ‘window management’ features required to use the software at a professional level. The windowing in vista, if you discount the ridiculous flip 3d switching gimmick, doesn’t seem to have changed an awful lot since win 3.1, when we all used to make do with 640×480 resolutions. Both linux and the Mac offer virtual desktops these days. There was a power toy which simulated this for XP, but it seems to have diasppeared from the Vista world. If anyone finds an equivalent, please let me know!

AddThis Social Bookmark Button

Don’t be lazy

June 18th, 2008 Nick Posted in java, rants and opinions | No Comments »

I’ve seen far too many bugs lately involving lazy initialization.

In theory lazy initialization might seem a good idea. Why do extra work up front which might not be needed?

The problem is that it is simply too easy to introduce bugs when state is not completely loaded after construction. For example, a project I recently worked on made extensive use of init() methods to lazily load state on demand. The constructor would not do the initialization. Instead, each getter method would check whether initialization was complete, and if not kick off an init() process before returning data.

The reasons for this were fairly convincing. The loading of the state required a call to a database, which was slow. But the problem was that this lazy initialization pattern soon spread throughout the codebase like a rash. Soon it was rare to find a class which was guaranteed to be ready for use after construction.

Still other classes used lazy loading as a speculative performance optimization. Table models received events which invalidated their internal state. Instead of recalculating immediately, they propagated events to their listeners, delaying their own recalculation. The models would recalculate only when a client class called a method to ask for data, and forced a the model to check its state and recalculate. Again, it sounded good - why take on the overhead of immediate recalculation if your class has no active listeners?

The original coders left. The code base gradually expanded to more than a million lines of code. New programmers arrived. Predictable problems emerged.

In many cases, the new programmers would simply fail to realise that an object was not ready to use until its init method had been called. Init methods had become a part of some key abstractions - although in the vast majority of cases subclasses did not actually require any special initialization. So most objects ended up with an init method, just to cater for the few places where it was really necessary. Confusion reigned as to when and where initialization should take place.

Interfaces changed and classes needed to be modified. It was all too easy to forget to check the initialization status when adding methods to existing classes. Strange errors occurred in the table models. The data had changed some time before, but since the recalculations were delayed it was hard to work out from the logs what had actually triggered the problem. Sometimes the original coders had made mistakes and forgotten to check the initialization state for some methods. In other subclasses had overridden methods and forgotten to include the check. Problems could emerge quite unexpectedly, such as when the ordering of client class method calls changed. This often caused strange data corruption or null pointer exceptions at runtime, which brought down components.

The basic OO tenet that an object should be ready for use after construction really does make a lot of sense - try very hard to avoid lazy initialization wherever possible. It may seem clever, but it probably isn’t. If it seems that lazy initialization is the only way, reconsider every alternative design. Simplicity is key, and lazy initialization or lazy recalculation is rarely, if ever, simple. You’ll likely save yourself some headaches in the short term, and in the long term you’ll save even more for those who inherit the code once you have moved on.

AddThis Social Bookmark Button

Calculating a color gradient

May 12th, 2008 Nick Posted in java, swing | No Comments »

For a recent project I needed some code to calculate a colour gradient for different points on a scatter chart. The class below performs a simple interpolation between two colours, if you feed it a value between 0 and 1.

public class GradientCalculator {
        private Color c1;
        private Color c2;

        public GradientCalculator(Color c1, Color c2) {
            this.c1 = c1;
            this.c2 = c2;
        }

        /**
         * @param ratio - value between 0 and 1
         */

        public Color getColor(double ratio) {
            int red = (int) (c1.getRed() * (1 - ratio) + c2.getRed() * ratio);
            int green = (int) (c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio);
            int blue = (int) (c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio);
            int alpha  =(int) (c1.getAlpha() * (1 - ratio) + c2.getAlpha() * ratio);
            return new Color(red, green, blue, alpha);
        }
    }

AddThis Social Bookmark Button

JOptionPain - JOptionPane hidden behind always on top window crashes Swing UI

April 5th, 2008 Nick Posted in java | 1 Comment »

nb. this is now bug id 6690019

There is a bug in the java bug database (6519416) related to a similar issue, but it is closed and not fixed - perhaps the reviewer didn’t realise how serious this can be. I think this needs to be looked at again, since it has caused several terminal crashes in production systems I have been working on.

The problem is to do with the use of the ‘always on top’ feature for java.awt.Window. If JFrames in the application are set to always on top, a JOptionPane can be obscured by an always on top frame, and hence be inaccessible to the user. Since the JOptionPane is modal, you can’t interact with or move the always on top frame - so there is no way to reveal the JOptionPane in order to dismiss it. The whole UI just hangs. You can’t even alt-tab to reveal the option pane. The only way out is to kill the process.

There is no problem with the always on top frame is the parent of the JOptionPane - the problem only occurs if the parent is a normal frame, or the JOptionPane has a null parent set.
The following code replicates the problem

public class TestJOptionPaneAlwaysOnTopBug
{
    public static void main(String[] args) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run()
                    {
                        JFrame alwaysOnTopFrame = new JFrame("Test JOptionPane");
                        alwaysOnTopFrame.setSize(600, 400);
                        centreFrame(alwaysOnTopFrame);
                        alwaysOnTopFrame.setAlwaysOnTop(true);
                        alwaysOnTopFrame.setVisible(true);

                        JFrame normalFrame = new JFrame();
                        normalFrame.setSize(800, 600);
                        centreFrame(normalFrame);
                        normalFrame.setVisible(true);

                        JOptionPane.showMessageDialog(normalFrame, "Can't you see me?");
                    }
                });
    }

    private static void centreFrame(JFrame myFrame)
    {
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (d.width - myFrame.getWidth()) / 2;
        int y = (d.height - myFrame.getHeight()) / 2;
        myFrame.setLocation(new Point(x, y));
    }
}

There is a workaround, described in the bug report above, which involves creating the dialog for the JOptionPane explicitly and setting it to be always on top before it is displayed. This seems to fix things, at least on the Windows platform. However, if you use the standard JOptionPane static methods to show a dialog, always on top is not set. I think it possibly should be - it seems unlikely that one would ever want to show an option pane which is not on the top. Perhaps there is a corner case here which is not obvious?

AddThis Social Bookmark Button

Doubled up

April 4th, 2008 Nick Posted in java | No Comments »

Can you guess the output of the code below? And no, it isn’t a compilation failure, even I can write code which compiles (at least after enough coffee)

public static void main(String[] args) {
        double d1 = Double.NaN;
        double d2 = Double.NaN;
        String verdict = "Not guilty";

        if ( d1 == d2 ) {
            if ( ! new Double(d1).equals(d2) ) {
                    verdict =  0 < Double.MAX_VALUE ?
                         "less than MAX_VALUE" :
                         "greater than MAX_VALUE";
            }
        } else {
            verdict = 0 > Double.MIN_VALUE ?
                    "greater than MIN_VALUE" :
                    "less than MIN_VALUE";
        }
        System.out.println(verdict);
    }



Well in fact it prints out ‘less then MIN_VALUE’, so if you got that result - well done!
There are two slightly counter intuituve aspects to this example.

Firstly Double.NaN != Double.NaN. although new Double(Double.NaN).equals(Double.NaN);

This is reasonably widely known, but also the cause of many bugs, since it is all too easy to forget the == comparator does not work in this case. To be safe you have to remember to use the isNaN() method on Double, if testing NaN conditions.

Secondly, since Double.MAX_VALUE is the maximum value a Double can take (apart from inifinity), it might be natural to think that Double.MIN_VALUE is the minimum value a Double can take. In fact, it is not - it is actually the minimum positive value a Double can take! Easy to overlook, and once again, a potential cause of many bugs.

We hit a bug with this recently when writing a max value calculator which took MIN_VALUE as its starting point, and iterated through a set of values. During the iteration, if a subsequent value was higher than the currently stored max value, its value was taken as the new max. This all worked brilliantly - until we ran the calculator against a number set consisting of just negative values, in which case the result was returned as MIN_VALUE!

Surely a better name for this constant would be MIN_POSITIVE_VALUE.




AddThis Social Bookmark Button

jmap and jstack - getting a heap dump and stack trace from a running JVM

February 21st, 2008 Nick Posted in java, unix | No Comments »

The project I’m working on currently has many server side java components running on linux. One of these in particular has been experiencing severe memory leaks when running in our production environment (but not UAT, surprisingly!)

It turns out there is a tool provided with sun’s jdk 1.5 + which will allow you to get a snapshot of the heap for a running process, without you having to have started the jvm with any particular options set. This tool is called jmap

running:
jmap -histo pid
where pid is the process id on a linux box

will give you a snapshot of the heap which looks like the below:

java -histo pid

Object Histogram:

Size    Count       Class description
-------------------------------------------------------
77928   583        char[]
55696   131        byte[]
8816    29  * ObjArrayKlassKlass
8520    355 java.lang.String
8272    215 java.lang.Object[]
4080    85  java.nio.HeapByteBuffer
3984    83  java.nio.HeapCharBuffer
3608    41  java.lang.Class
2456    19  int[]
1368    57  java.util.Hashtable$Entry
1288    16  * ConstMethodKlass
1208    31  java.lang.String[]
1120    14  java.util.HashMap$Entry[]
1040    10  java.util.Hashtable$Entry[]
1008    14  java.lang.reflect.Field
960     3    * InstanceKlassKlass
etc.

The most useful thing here is probably the object class count. There is a chance this could help you identify an area of your app which is producing an unexpected number of instances of a given class. Other jmap options give you a dump file in different formats - so this is worth investigating too.

There is an equivalent tool jstack (jstack pid), which dumps stack information for each of the running threads. Probably useful for diagnosing deadlocks etc.

The nice thing about both of these tools is that you don’t need to have started the jvm with any specific options. These tools just connect and work - so you don’t need to have planned your memory leak in advance :)

They only work on unix right now, unfortunately.
There is a good article on new tools with jdk1.6 here

nb. if jstack fails you may be able to get a thread dump on unix using kill -3 {pid}
Here is another useful link for suggestions on diagnosing performance problems

And here is a good link to help diagnose java app problems in general

AddThis Social Bookmark Button

Drag and drop into empty table not working?

January 25th, 2008 Nick Posted in java, swing | No Comments »

This is a known gotcha from the early days of Swing, related to bug id 4310721

The symptom is that while drag and drop works fine into tables which are populated, trying to drop into a table with no rows, or drop data beneath the populated rows, does not work. The cause of this is that the table does not automatically expand to fill the area available to it in the JScrollpane viewport.

As of jdk1.6 this is fixed on JTable itself. You just need to call myJTable.setFillsViewportHeight(true)

If you do not have the great glory of 1.6 available to you, you will have to extend JTable and override the getScrollableTracksViewportHeight() method as below:

public class TrackViewportJTable extends JTable {

    public TrackViewportJTable(TableModel tableModel, TableColumnModel tableColumnModel) {
        super(tableModel, tableColumnModel);
    }

    public TrackViewportJTable(TableModel tableModel) {
        super(tableModel);
    }

    public boolean getScrollableTracksViewportHeight() {
        // fetch the table's parent
        Container viewport = getParent();

        // if the parent is not a viewport, calling this isn't useful
        if (! (viewport instanceof JViewport)) {
            return false;
        }

        // return true if the table's preferred height is smaller
        // than the viewport height, else false
        return getPreferredSize().height < viewport.getHeight();
    }
}

The above is based on the example in Shannon Hickey’s blog.
For a more complete description of the problem, and its solution, see his blog entry here

AddThis Social Bookmark Button

Tricked by short circuit operators

January 17th, 2008 Nick Posted in java | No Comments »

I am currently feeling suitably humbled, having fallen into a nasty coding trap. At least in this case it didn’t cause a major industrial disaster (please shoot me if I ever start work in the aviation industry!)

So just to make the humiliation public, the following was the cause of my disgrace - I had a test, similar to the below:

return myString != null && ! myString.equals("wibble") && ! myString.equals("squork");

So that’s all OK, isn’t it, even if it isn’t particularly nice code? - if the string is null the first test will evaluate to false, and then the short circuit operator will prevent the other two tests from being evaluated. Hence a null pointer cannot occur.

Well yes. In fact, that is correct - the above works OK. My problem was that I duplicated and changed the logic, without thinking through the consequences, and introduced an or operator into the mix:

return myString != null && myString.equals("wibble") || myString.equals("squork");

Looks similar, at a glance, and again the short circuit operator should prevent any null pointer. Or should it?

In fact in this case, no. It all goes pear shaped, and horribly so. The reason is to do with operator precedence. What actually happens is that since && has a higher precedence than ||, the way the compiler actually interprets the above is this:

return ( myString != null && myString.equals("wibble") ) || myString.equals("squork");

which, if myString is null, becomes:
return false || myString.equals("squork");

So the second of the myString.equals tests is still evaluated, and a null pointer results. Luckily these lines of code weren’t wired into flight control.

I think I had been lulled into a false sense of security by the short circuit operator construct. Well, that’s one more mistake I’ll never make again. But clearly, I needed to refresh my knowledge of the rules of operator precedence !





AddThis Social Bookmark Button

Maven presentation

December 5th, 2007 Nick Posted in java, musings | No Comments »

Why do so many projects reinvent the wheel when it comes to build scripts? Maven applies the principles of convention over configuration to project build and setup. It also provides management of dependencies between modules, something which can rapidly get out of hand in a project environment of any size or scale.

I was immediately hooked on Maven when I first started using it several years ago, and Maven has come a long way since then. The new Maven 2 integration in Intellij 7 is a fantastic step forward. This should really reduce the learning curve for developers moving between projects.

Here is a copy of the powerpoint for a recent introduction to Maven presentation I gave at work, covering some of the basics.

MavenPresentation.ppt

The links below may also be helpful:

Maven Project Front Page
Build lifecycle phases in Maven, and mappings from lifecycle phases to maven plugins
Maven the definitive guide - online book
Search the maven repository at www.mvnrepository.com

AddThis Social Bookmark Button