Setting up an IMAP account with SSL does not work with Android 2.1

July 1st, 2010 Nick Posted in hardware | No Comments »

I had this problem after upgrading my Hero to Android 2.1

I previously had an imap mailbox working fine, with an SSL connection, but setting it up again under 2.1 seemed to get me nowhere.
After going to manual setup and entering the incoming server details, clicking continue would simply take me back to the same page – not to the next ‘configure outgoing mailserver’ screen.

Since HTC pushed out the over the air upgrade for the Hero in the last few days, I guess a lot of people may now be in the same boat

It turns out this is a bug – really at this point, android should be showing the ‘accept certificate’ dialog, in cases where you don’t have a signed certificate on your mailserver

The good news is – there is a workaround.

Simply put in an incorrect value for the imap server first time around
Android will tell you that it can’t connect to the server – but will still let you proceed and add an outgoing mail server etc, and finish configuring the account.

Then, when the account is configured, simply go to the account settings and enter a correct server.
This time, Android should correctly show the ‘accept certificate’ dialog, and you should be able to proceed as normal.

Thank goodness for this workaround! I was getting seriously worried my new 2.1 Hero wouldn’t work with my email server.

AddThis Social Bookmark Button

New jtimeseries project on sourceforge

May 20th, 2010 Nick Posted in java, jtimeseries, web, xml | No Comments »

For the last year and a half I have been hard at work at a new open source project jtimeseries.

This has finally made it onto sourceforge!

So what can you do with this jtimeseries thing?

Quite a lot, already. Let me explain how this project was conceived….

Initially, I was looking for a java based API which I could use to capture metrics for a Swing application I was working on. Rather than store the raw values I was collecting, I needed a way to capture, for example, the mean value of a certain measurement over a time period (e.g. the mean price latency over the last five minutes, or the 90th percentile heap memory). As well as capturing and storing the stats, I also needed ui visualizer components to enable viewing of the data, and wanted to also show the stats collected via an embedded web server in the application.

how about storing the data?

A logical extension once the core API was up and running was to provide a lightweight database component to persist the timeseries data on the server side, in a round robin file format (noting here that there is no java api for rddtool presently, which gave me ample license to write one myself I think!). The server can store stats from multiple sources – and you can subscribe to view the series from the ui.

collecting stats from jmx

The other really neat feature of the database, is that it can be configured to read in metrics data directly via the jmx management service of a running java app. This means that you can capture details, such as the memory and cpu load of your other java components without having to change their code and re-release them! You just need to have the jvm jmx management feature enabled, so that you can point a jconsole at the app and see values.

New release

So that’s how it all came about. We now have a stable release, 1.0.10, which you can find here

At present I am consulting for a company which now has two instances of the timeseries server, currently maintaining nearly 50,000 time series, which provide stats on the performance of dozens of our production and UAT components going back over a few months. The benefits of this are massive. It’s easy to spot performance problems before they become a major issue. Most importantly, before a release takes place, it’s easy to see from the stats whether a new component version has worse performance than its predecessor – without even having to fire up the profiler.

I’ll be adding more documentation on jtimeseries over the next couple of weeks



AddThis Social Bookmark Button

How to find the pid of a java process from code

March 3rd, 2010 Nick Posted in java | No Comments »

This blog has been quiet for a while, that’s about to change, but in the meantime I came across a very interesting way to get hold of the PID for your running java process from code, which I thought I’d put up straight away.

This makes use of the Management JMX beans to find the information, but the good news is that it seems you don’t have to do anything special, such as add VM system properties, to make it work.

Not sure this will work on every OS/vm, but on the ones I have tried there’s no problem.
Seems to work on both Windows on Linux

For me, the below produces:
ProcessName=[1136@iblongsw253311]
PID=[1136]

public static void main(String[] args) {
        try {
            RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean();
            String s = mx.getName();
            System.out.println("ProcessName=["+s+"]");
            String[] pidAndHost = s.split("@");
            if ( pidAndHost.length == 2) {
                int pid = Integer.valueOf(pidAndHost[0]);
                System.out.println("PID=[" + pid + "]");
            }
        }
        catch( Exception e) {
            System.out.println("Whoops, can't find a PID");
        }
    }
AddThis Social Bookmark Button

JTable setRowHeight causes slow repainting

June 6th, 2009 Nick Posted in java, swing | 5 Comments »

I’ve spent way too much time in the last few months fixing and optimising table rendering performance for a high performance Java application I’m working on at the moment. The problems were particularly hard to find becuase the app supports customization of almost every aspect of JTable UI, with custom rendering for rows, columns and individual cells according to user preferences. Some users would get terrible performance on some days, which would seem to disappear the next.

Some of the issues were hardware and graphics driver related, and there have been various minor and major victories along the way (more about these later), but just yesterday I found a very significant defect in JTable.tableChanged().

The problem occurs when you call setRowHeight(int row, int height) on a JTable, to set a customised table row height. You only need to do this once, and that causes JTable to initialize its internal rowModel to maintain the custom row heights. From that point onwards, any update to the TableModel (even if it is just an update event for a single cell()) will be processed by JTable.tableChanged() in such a way that the entire table component is marked as dirty. So this forces the RepaintManager to repaint the entire table every time, even for single cell updates.

The point at which everything appears to go wrong is at JTable line 4396 (in jdk 1.6.0_14) and line 3021 (in jdk 1.5.0_17), which is part of the processing for TableModel update events

// The totalRowHeight calculated below will be incorrect if
// there are variable height rows. Repaint the visible region,
// but don't return as a revalidate may be necessary as well.
if (rowModel != null) {
    repaint();
}

Essentially, if there is an internal rowModel set up (i.e the user has configured some custom row heights), then the call to repaint() in this snippit causes the entire JTable to be marked as dirty – so the RepaintManager repaints the entire table component rather than just the cells affected by an update.

The effect of this is dramatic. When I run my test class (included below):

***** Running test for table Standard JTable under 1.5.0_19
With all rows default height total time spent repainting table 24 millis
Setting custom row height for one row
With one custom row height total time spent repainting table 5427 millis
Thats 226 times slower than it should be to paint the table!

Here is a Fix for the issue

I’m pretty surprised this issue hasn’t been fixed already, since custom row heights can’t be all that rare. I have produced a workaround by extending JTable to override the tableChanged() handling for update events. Fixing this has solved major problems for our users whose tables were configured to require custom row heights.

This works fine for for me in 1.5.*.
It will also work for jdk 1.6.* but it does not support the 1.6 table row sorting (you’d need to find a way to fire sortedTableChanged() events to the sortManager to do this when the updates are processed)

   import javax.swing.table.TableModel;
import javax.swing.event.TableModelEvent;
import javax.swing.*;
import java.awt.*;


/**
 * Extends JTable to fix the broken repainting for updates when there are custom height rows
 * See http://www.objectdefinitions.com/odblog/2009/jtable-setrowheight-causes-slow-repainting/
 *
 * This fix does not support row sorting in jdk1.6 -
 * to support that would require firing sortedTableChanged to sortManager
 */

public class FixedForRowHeightJTable extends JTable {

    public FixedForRowHeightJTable() {
    }

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

    public void tableChanged(TableModelEvent e) {
        //if just an update, and not a data or structure changed event or an insert or delete, use the fixed row update handling
        //otherwise call super.tableChanged to let the standard JTable update handling manage it
        if ( e != null &&
            e.getType() == TableModelEvent.UPDATE &&
            e.getFirstRow() != TableModelEvent.HEADER_ROW &&
            e.getLastRow() != Integer.MAX_VALUE) {

            handleRowUpdate(e);
        } else {
            super.tableChanged(e);
        }
    }

    /**
     * This borrows most of the logic from the superclass handling of update events, but changes the calculation of the height
     * for the dirty region to provide proper handling for repainting custom height rows
     */

    private void handleRowUpdate(TableModelEvent e) {
        int modelColumn = e.getColumn();
        int start = e.getFirstRow();
        int end = e.getLastRow();

        Rectangle dirtyRegion;
        if (modelColumn == TableModelEvent.ALL_COLUMNS) {
            // 1 or more rows changed
            dirtyRegion = new Rectangle(0, start * getRowHeight(),
                                        getColumnModel().getTotalColumnWidth(), 0);
        }
        else {
            // A cell or column of cells has changed.
            // Unlike the rest of the methods in the JTable, the TableModelEvent
            // uses the coordinate system of the model instead of the view.
            // This is the only place in the JTable where this "reverse mapping"
            // is used.
            int column = convertColumnIndexToView(modelColumn);
            dirtyRegion = getCellRect(start, column, false);
        }

        // Now adjust the height of the dirty region
        dirtyRegion.height = 0;
        for ( int row=start; row <= end; row ++ ) {
            dirtyRegion.height += getRowHeight(row);  //THIS IS CHANGED TO CALCULATE THE DIRTY REGION HEIGHT CORRECTLY
        }
        repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height);
    }

}

The following Test demonstrates the problem, and that FixedForRowHeightJTable solves it

This test pops up a JTable in a frame and then changes cell values to trigger repaints.
While doing this we replace the standard RepaintManager with a TimingRepaintManager, which keeps track of the total time spent by the Swing event thread painting the table
We first run the test for a standard JTable, then for my fixed version, with the following results:

***** Running test for table Standard JTable under 1.5.0_19
With all rows default height total time spent repainting table 24 millis
Setting custom row height for one row
With one custom row height total time spent repainting table 5427 millis

***** Running test for table FixedForRowHeight JTable under 1.5.0_19
With all rows default height total time spent repainting table 2 millis
Setting custom row height for one row
With one custom row height total time spent repainting table 25 millis

Needless to say, I’ve submitted a bug report for this one!
(although technically once might argue its an RFE, since the table still gets painted, anything which degrades performance this much is a bug in my book!)

import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;

/**
 * Created by IntelliJ IDEA.
 * User: Nick Ebbutt
 * Date: 06-Jun-2009
 * Time: 13:34:58
 *
 * A demonstration of JTable repainting bug for custom row heights
 */

public class DemoForJTableCustomRowHeightRepaintBug {

    private static final int COL_COUNT = 40;
    private static final int ROW_COUNT = 50;
    private static TimingRepaintManager timingRepaintManager;
    private static JTable table;
    private static FixedForRowHeightJTable fixedTable;

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                timingRepaintManager = new TimingRepaintManager();
                RepaintManager.setCurrentManager(timingRepaintManager);
                table = new JTable(new TestTableModel());
                fixedTable = new FixedForRowHeightJTable(new TestTableModel());
            }
        });

        runTestForTable("Standard JTable", table);
        runTestForTable("FixedForRowHeight JTable", fixedTable);
    }

    private static void runTestForTable(String description, final JTable table) throws Exception {
        System.out.println("\n***** Running test for table " + description + " under " + System.getProperty("java.version"));
        showTable(table, description);
        timingRepaintManager.resetTotalRepaintTime();
        runTableModelUpdates(table.getModel());

        System.out.println("With all rows default height total time spent repainting table " + timingRepaintManager.getTotalRepaintTime() + " millis");

        System.out.println("Setting custom row height for one row");
        setRandomRowHeight(table);

        timingRepaintManager.resetTotalRepaintTime();
        runTableModelUpdates(table.getModel());
        System.out.println("With one custom row height total time spent repainting table " + timingRepaintManager.getTotalRepaintTime() + " millis");
    }

    private static void setRandomRowHeight(final JTable table) throws InterruptedException, InvocationTargetException {
        //now just set one row to a custom height and run the repaint timing test again
        SwingUtilities.invokeAndWait(
            new Runnable() {
                public void run() {
                    table.setRowHeight(getRandomRowOrCol(ROW_COUNT), 100);
                }
            }
        );
    }

    public static void showTable(final JTable t, final String name) throws Exception {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                JFrame f = new JFrame(name);
                f.getContentPane().add(new JScrollPane(t));
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setSize(new Dimension(1024,768));
                f.setVisible(true);
            }
        });
    }

    public static void runTableModelUpdates(final TableModel tableModel) {
        for ( int loop=0; loop < 500; loop++) {
            try {
                SwingUtilities.invokeAndWait(new Runnable() {
                    public void run() {
                        tableModel.setValueAt("Wibble", getRandomRowOrCol(ROW_COUNT), getRandomRowOrCol(COL_COUNT));
                    }
                });
                Thread.sleep(10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //record the total time spent repainting
    private static class TimingRepaintManager extends RepaintManager {
        private volatile long totalTime;

        public void paintDirtyRegions() {
            long startTime = System.currentTimeMillis();
            super.paintDirtyRegions();
            totalTime += System.currentTimeMillis() - startTime;
        }

        public long getTotalRepaintTime() {
            return totalTime;
        }

        public void resetTotalRepaintTime() {
            this.totalTime = 0;
        }
    }


    private static class TestTableModel extends DefaultTableModel {
        public TestTableModel() {
            setColumnCount(COL_COUNT);
            for (int row=0; row < ROW_COUNT; row++) {
                addRow(createRow(row));
            }
        }

        private Object[] createRow(int row) {
            String[] colNames = new String[COL_COUNT];
            for ( int col=0; col<COL_COUNT; col++) {
                colNames[col] = "Cell " + row + ":" + col;
            }
            return colNames;
        }
    }

    public static int getRandomRowOrCol(int maxVal) {
        return (int)(Math.random() * maxVal);
    }

    /**
     * Extends JTable to fix the broken repainting for updates when there are custom height rows
     *
     * This fix does not support row sorting in jdk1.6 -
     * to support that would require firing sortedTableChanged to sortManager
     */

    private static class FixedForRowHeightJTable extends JTable {

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

        public void tableChanged(TableModelEvent e) {

            //if just an update, and not a data or structure changed event or an insert or delete, use the fixed row update handling
            //otherwise call super.tableChanged to let the standard JTable update handling manage it
            if ( e != null &&
                e.getType() == TableModelEvent.UPDATE &&
                e.getFirstRow() != TableModelEvent.HEADER_ROW &&
                e.getLastRow() != Integer.MAX_VALUE) {

                handleRowUpdate(e);
            } else {
                super.tableChanged(e);
            }
        }

        /**
         * This borrows most of the logic from the superclass handling of update events, but changes the calculation of the height
         * for the dirty region to provide proper handling for repainting custom height rows
         */

        private void handleRowUpdate(TableModelEvent e) {
            int modelColumn = e.getColumn();
            int start = e.getFirstRow();
            int end = e.getLastRow();

            Rectangle dirtyRegion;
            if (modelColumn == TableModelEvent.ALL_COLUMNS) {
                // 1 or more rows changed
                dirtyRegion = new Rectangle(0, start * getRowHeight(),
                                            getColumnModel().getTotalColumnWidth(), 0);
            }
            else {
                // A cell or column of cells has changed.
                // Unlike the rest of the methods in the JTable, the TableModelEvent
                // uses the coordinate system of the model instead of the view.
                // This is the only place in the JTable where this "reverse mapping"
                // is used.
                int column = convertColumnIndexToView(modelColumn);
                dirtyRegion = getCellRect(start, column, false);
            }

            // Now adjust the height of the dirty region
            dirtyRegion.height = 0;
            for ( int row=start; row <= end; row ++ ) {
                dirtyRegion.height += getRowHeight(row);  //THIS IS CHANGED TO CALCULATE THE DIRTY REGION HEIGHT CORRECTLY
            }
            repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height);
        }
    }

}
AddThis Social Bookmark Button

SwingCommand part 7 – Composite Commands

May 2nd, 2009 Nick Posted in Uncategorized | No Comments »

There are occasions when it is useful to group commands together and execute several in combination. SwingCommand provides a CompositeCommandTask which allows you to group commands together in a single task which executes them sequentially.

TaskListeners on the CompositeCommandTask receive progress events as each child command is processed. The example below creates a String progress value to describe the current child command being processed.

Cancelling the composite task will cause the currently processing child command to be cancelled (if it supports cancellation), and will cause the composite task to abort processing for any remaining child command tasks. The reverse is also true – if the currently processing child command’s task is cancelled, this will cause the composite task to be cancelled and abort early.

If any of the child commands fail, the composite task will also fail with a CompositeCommandTaskException, which has the child task’s exception as the cause.

Here is a simple example of a composite task:

  SwingCommand loadThreeUsersMessages = new SwingCommand() {
 
      protected Task createTask() {
 
          CompositeCommandTask compositeTask = new CompositeCommandTask() {
 
              //let's send progress as a String update to any TaskListeners
              protected String getProgress(int currentCommandId, int totalCommands, Task currentChildCommand) {
                  return "Now running number " + currentCommandId + " out of " + totalCommands + " commands";
              }
          };
 
          compositeTask.addCommand(new LoadMessagesCommand("User 1"));
          compositeTask.addCommand(new LoadMessagesCommand("User 2"));
          compositeTask.addCommand(new LoadMessagesCommand("User 3"));
          return compositeTask;
      }
  };
 
  loadThreeUsersMessages.execute();

The composite task implements the getProgress() method to generate the String used in the progress event.

AddThis Social Bookmark Button

SwingCommand part 6 – Cancellation

May 2nd, 2009 Nick Posted in Uncategorized | No Comments »

SwingCommand has support for cancellable commands. To support cancellation for a Task it is easiest if the Task extends InterruptibleTask. InterruptibleTask helps to implement the logic necessary to interrupt the background thread if cancel() is called.

When you invoke command.execute() on a SwingCommand instance, a reference to the Task which is created to handle the execution is returned from the execute() method. Getting the reference to the Task which is running can be useful – for Tasks which support the cancel operation, you may want to cancel the task by calling task.cancel()

To implement cancellation correctly, your Task must be able to respond to the interrupt request. There are two main cases to consider:

  • Interrupting a task which is blocked on IO, or on some other blocking call
  • Interrupting a task programatically by checking the isInterrupted() status periodically

Lets look at the first of these, interrupting a task which is blocking:

//interruping a background task with cancel

  SwingCommand c = new SwingCommand() {
      protected Task createTask() {

            return new InterruptibleTask() {

                public void doInBackground() throws InterruptedException {
                    Thread.sleep(10000);
                }

                public void doInEventThreadIfNotCancelled() {
                    textArea.setText("Task was not cancelled");
                }
        };
      }
  };

  //let's pop up a option pane if the task is cancelled
  c.addTaskListener(new TaskListenerAdapter() {
      public void cancelled(Task task) {
              JOptionPane.showMessageDialog(frame, "Task was Cancelled");
      }
  });


  Task t = c.execute();

  //and then a while later, from any thread...
  t.cancel();

In the example above the Task extends InterruptibleTask. During the doInBackground() handler, the background thread is blocked for a time in the call to Thread.sleep(). When task.cancel() is called by any thread, the InterruptibleTask logic will trigger thread.interrupt() on the background thread. This will result in an InterruptedException being generated by the sleep() method. Because cancel() was called, InterruptibleTask will catch the InterruptedException and the Task will finish with cancelled set to true (task.isCancelled() == true).

Note, if cancel() had not been called, the exception would have been allowed to propagate through causing TaskListeners to receive an error message, and the command would finish in the ERROR state.


What if cancel is called before or after the background processing?

If the call to task.cancel() occurs before background processing starts, the doInBackground() handler will not be called, and cancellation will always succeed. If the call to cancel() occurs after doInBackground() has returned, the call to cancel will not succeed – in this case and the task will end with isCancelled() == false.

The doInEventThreadIfNotCancelled() method is only called if the task is not cancelled. (You could alternatively override doEvenIfCancelled() if you wanted to do some post-processing in the event thread regardless of cancellation).


Interrupting a background task using custom logic

Sometimes a blocked thread will not respond automatically to thread.interrupt(). This is the case during some JDBC queries, for example. In some cases you have to implement extra logic to interrupt the task, and you can do this by overriding the doInterrupt() method. This example demonstrates how you might handle interrupting a query on a JDBC statement:

  SwingCommand c = new SwingCommand() {
      protected Task createTask() {

            return new InterruptibleTask() {

                private volatile Statement s;
                private StringBuffer text = new StringBuffer();

                public void doInBackground() throws SQLException {
                    s = connection.createStatement();
                    ResultSet r = s.executeQuery("select text from Message");
                    while(r.next()) {
                        text.append(r.getString(1)).append("\n");
                    }
                }

                protected void doInterrupt() throws SQLException {
                    Statement statement = this.s;
                    if ( s != null) {
                        s.cancel();
                    }
                }

                public void doInEventThreadIfNotCancelled() {
                    textArea.setText(text.toString());
                }
        };
      }
  };

  Task t = c.execute();

  //do something else for a while, and then call:
  t.cancel();

In the example above, the basic processing is the same, but this time we have also overridden the doInterrupt() method, to close the JDBC statement if the background query is interrupted. This should cause the statement.executeQuery() method to throw an SQLException. Because cancel() has been called, this exception will be treated as the result of a cancellation, and the task will end with isCancelled() == true.

Interrupting a task by checking isInterrupted()

There’s just one more case to demonstrate. How to handle a non-blocking cancel. This is actually quite simple – you just need to periodically check the isInterrupted() method, and return early if necessary:

SwingCommand c = new SwingCommand() {
      protected Task createTask() {
         
        return new InterruptibleTask() {

            public void doInBackground() throws InterruptedException {
                for ( int loop=0; loop < 1000000; loop ++) {
                    if ( isInterrupted() ) {
                        break;
                    }
                }
            }

            public void doInEventThreadIfNotCancelled() {
                textArea.setText("Task was not cancelled");
            }
        };
      }
  };

Here the doInBackground() handler enters a processing loop. On each iteration, it checks to see if isInterrupted() is true – this will be the case if cancel() has been called on the task. If so, it breaks the loop to end the processing early.

Note that a task is considered cancelled even if the doInBackground() does not return early, provided that when the doInBackground() method returns the background thread still has its interrupted flag set.

Whew – that’s a fair amout to absorb. But the thing to take away is that extending InterruptedTask makes handling cancel easy. There is very little boilerplate code in the examples above, and you shouldn’t need to work too hard to get this right.

AddThis Social Bookmark Button

SwingCommand part 5 – Task States and Error Handling

May 2nd, 2009 Nick Posted in Uncategorized | No Comments »

Task States

It is possible to find the current state of a Task instance directly by calling task.getExecutionState();
There are six ExecutionStates: NOT_RUN, PENDING, STARTED, SUCCESS, CANCELLED and ERROR.

A task starts in state NOT_RUN. During the call to command.execute(), the state will change to PENDING. Once task processing begins (which may be some time later if the task is queued for processing or is blocked waiting for a thread from a thread pool) the state moves to STARTED. The final state will be either SUCCESS , ERROR or CANCELLED. In the case that a Task finishes in ERROR, you can obtain the Exception that caused the error by calling task.getExecutionException()

If a SwingCommand task handler method ( doInEventThread() or doInBackground() ) throws an Exception the task is considered to have failed. Any TaskListeners will receive an error() callback, and the task will end in the ExecutionState.ERROR state.

Ending a SwingCommand Early

If an exception is thrown during doInBackground(), the doInEventThread() handler will not be called. Instead, processing is aborted before doInEventThread() is called. This makes sense, because in most cases we will not want to update the ui if, for example, a task loading data failed.

However, sometimes you will need to perform error handling in the Swing Event Thread, or perform some processing whether or not an error occurs or the task is cancelled. For example you may need to stop a progress animation. These cases are best handled by a TaskListener, in the error() method, or the finished() method respectively.

The finished() callback always occurs, no matter if the task succeeds, fails or is cancelled. The TaskListener methods also allow you to perform handling only on success (the success() callback).

  SwingCommand c = new SwingCommand() {
      protected Task createTask() {
          return new BackgroundTask() {

              public void doInBackground() throws Exception {
                  //this method throws an exception instead of returning
                  throw new Exception("woe");
              }

              public void doInEventThread() throws Exception {
                  //So we'll never get here!
              }
          };
      }
  };

     
  c.addTaskListener(new TaskListenerAdapter() {
     
      public void error(Task task, Throwable error) {
          JOptionPane.showMessageDialog(frame, "Failed to Load Messages");
      }
   
      public void finished(Task task) {
          //the task will finish in the ERROR state since doInBackground() threw an Exception
          assert(Task.ExecutionState.ERROR == task.getExecutionState());
       
          //we can get the error back by calling task.getExecutionException()
          Throwable cause = task.getExecutionException();
      }
  });

  c.execute();
AddThis Social Bookmark Button

SwingCommand part 3 – Showing Progress

May 2nd, 2009 Nick Posted in Uncategorized | No Comments »

The progress animation triggered by the TaskListener in the previous example would at least inform the user that a SwingCommand is executing. However, sometimes it may be useful for a long running command to show publish interim results, or simply post more descriptive progress updates.

To help with this, as well as allowing you to set the generic type for parameters to your SwingCommand, the SwingCommand class also allows you to specify a generic type for a progress update. The following example demonstrates perhaps a simple case, in which an Integer progress event is fired:

//Here I have updated the ClearMessagesCommand to publish progress messages as a Integer

  class ClearMessagesCommand extends SwingCommand<String,Integer> {

      public ClearMessagesCommand() {
      }

      public Task<String,Integer> createTask() {

          return new BackgroundTask<String,Integer>() {

              public void doInBackground() throws Exception {
                  fireProgress(1);

                  String userName = getParameters();
                  Statement s = connection.createStatement();
                  s.execute("delete from Message where User = " + userName);

                  fireProgress(2);
              }

              public void doInEventThread() {
                  fireProgress(3);    
              }
          };
      }
  }

  SwingCommand<String,Integer> c = new ClearMessagesCommand();
  c.execute("Nick");

  c.addTaskListener(new TaskListenerAdapter<Integer>() {
      public void progress(Task task, Integer progressDescription) {
          progressLabel.setText("stage " + String.valueOf(progressDescription));
      }
  });

You could do more sophisticated things by firing progress, and progress events make it easy to update the UI safely – remember that these messages are received on the Swing Event thread even if fired from doInBackground().

For example, you could use this mechanism to gradually populate messages into an ‘inbox’ while reading mail messages from a remote server. Or you could send an Integer progress update representing a percentage value, to update a progress bar with the current percentage of work completed by a background thread.

AddThis Social Bookmark Button

SwingCommand part 2 – TaskListeners

May 2nd, 2009 Nick Posted in Uncategorized | No Comments »

A common requirement in User Interfaces is to show an animation while a background task runs. How might this be accomplished using SwingCommand?

The following example shows how you can add a TaskListener to a command. The TaskListener will receive events as the command executes, and start and stop an animation.

TaskListeners always receive their events on the Swing Event thread, even if the Task is a BackgroundTask.

//TaskListeners always receive their events on the Swing event thread

  LoadMessagesCommand command = new LoadMessagesCommand("My User");

  TaskListener animationListener = new TaskListenerAdapter() {
      public void pending(Task task) {
          startProgressAnimation();
      }

      public void finished(Task task) {
          stopProgressAnimation();
      }
  };

  command.addTaskListener(animationListener);
  command.execute();
  }

Every time the command is executed, the SwingCommand creates a new Task instance, and the TaskListener will receive events while the Task runs.

It’s also possible to add a TaskListener to receive events for a single SwingCommand invocation, by passing it as a parameter to the execute() method:

//Let's add a listener to perform some error handling..
//this listener will not receive events on any subsequent executions:

  LoadMessagesCommand command = new LoadMessagesCommand("My User");

  command.execute(new TaskListenerAdapter() {
      public void error(Task task, Throwable error) {
          System.err.println("Oops, perhaps our database is offline");
      }
  });

The ability to add TaskListeners to SwingCommands is a key feature of SwingCommand, and it can be very convenient. For example, you could create several different commands and add a shared listener which tracks the background tasks and updates progress components on your UI. This listener will receive events on the Swing Event thread whenever one of the commands is executed, no matter which thread or which class actually executes it.

Separation of concerns

TaskListeners are a very useful mechanism. They allow you to separate the logic for handling progress animations, and error handling logic, from the main Task processing logic. You could, for example, provide a TaskListener which performs consistent error handling for all of the commands in your application. This is a good separation of concerns. Mixing that logic in with the main command processing logic tends to clutter the code up and make classes less easy to reuse – and there are certainly cases where you might want different error handling depending on the situation in which the SwingCommand is executed (e.g. if it’s executed in response to a button click in a Dialog, you may want to show an error message in the Dialog, rather than the main UI frame). To achive this, you can add some listeners to the SwingCommand, which will get notified whenever it is executed, and others context specific listeners can be passed as parameters to SwingCommand.execute().

The TaskListener interface

There are actually six listener methods in the TaskListener interface. Some of these are always invoked, others are only invoked if a Task enters a specific state (ERROR or SUCCESS) for example. To avoid having to implement all the methods, you can extend TaskListenerAdapter.

The full definition of the TaskListener interface is below:

/**
 * Implement this interface to listen to the progress of a task
 * Callbacks on this interface are guaranteed to be received on the AWT event thread,
 * even if fired by an BackgroundTask
 *
 * These callbacks provide an easy and safe way to update the UI to show the progress of a task.
 *
 * <P> - the type of Progress object that this TaskListener will receive
 */

public interface TaskListener<P> {

    /**
     * The callback to pending is triggered when command.execute() is called
     * If the Executor running the task queues the task or blocks waiting for
     * a thread, it may be some time before started() is invoked.
     */

    void pending(Task task);

    /**
     * Called when the task starts processing. For BackgroundTask this callback
     * takes place just before doInBackground is called. For SimpleTask just before doInEventThread
     */

    void started(Task task);

    /**
     * This callback may take place at any time during task execution, to indicate progress
     */

    void progress(Task task, P progress);

    /**
     * Called when the task reaches the SUCCESS end state
     * This callback takes place once a command has successfully completed (was not cancelled,
     * and did not throw an Exception resulting in a callback to error())
     */

    void success(Task task);

    /**
     * Called when the task reaches the ERROR end state
     * This callback takes place if an exception is raised during task execution, which prevents
     * successful completion
     */

    void error(Task task, Throwable error);

    /**
     * Called when the task reaches the CANCELLED end state
     * This callback takes place if the task is cancelled.
     * @param task
     */

    void cancelled(Task task);

    /**
     * This callback always takes place once the task has finished, whether or not the
     * task finishes in ERROR, SUCCESS or CANCELLED states
     */

    void finished(Task task);
}
AddThis Social Bookmark Button

Lower bound wildcards in java – how to apply the get and put principle

February 27th, 2009 Nick Posted in java | No Comments »

I recently saw an answer to a generics question on stack overflow where an incorrect (or at least misleading) answer has been voted up to the top. Sometimes generics are just a bit unintuitive.

Here is the example in a nutshell -

   addToList(List<? super Shape> l) {
    l.add(new Object());
}

 // That should work, right? After all List<? super Shape> is defined so that it can hold
 // any objects which implement a superclass of Shape....

In fact, the code above would not compile. That’s the wrong way to interpret the lower bound wildcard. The variable l actually refers to a List which may be restricted to contain any valid superclass of Shape – and we don’t know exactly what type of List it is from the lower bound reference. It may actually be a List of Drawable (if Shape extends Drawable), in which case adding an Object to it would not be safe – since an Object is not necessarily Drawable. It may also be a List of Shape instances (since Shape is the lower bound), in which case adding an Object to it would also be invalid. That’s why the example above does not compile.

There is an important principle set out in Java Generics and Collections, called the ‘Get and Put Principle’ which helps to explain when to use lower and upper bound wildcards

Use an extends wildcard when you only get values out of a structure, use super wildcard when you only put values into a structure, and don’t use a wildcard when you both get and put.

Proper use of this rule can make your classes more flexible. Partly to make sure I’ve got this fully straightened out in my own head, I’ve put together an example which illustrates the get and put principle, and helps to explain upper and lower bound wildcards:

// Example of the Get and Put Principle

    private class Drawable {}

    private class Shape extends Drawable {}

    private class Circle extends Shape {}

    public void testPut() {
        putShapeInto(new ArrayList<Object>());
        putShapeInto(new ArrayList<Drawable>());
        putShapeInto(new ArrayList<Shape>());
    }

    //flexible - can take a List of any superclass of Shape
    public void putShapeInto(List<? super Shape> l) {
        // We don't know what the type of list l is, but we know it is Shape or a superclass of Shape
        // therefore, it is always a valid destination for Shape instances
        l.add(new Shape());

        // l.add(new Object());
        // ...will not compile. The type of l may be any valid superclass of Shape
        // e.g. It may be <Drawable>, not all Objects are Drawable

        // Shape s = l.get(0);
        // ...will not compile. l may be List<Drawable>, and not all Drawables are necessarily Shapes
    }

    public void testGet() {
        getShapeFrom(new ArrayList<Shape>());
        getShapeFrom(new ArrayList<Circle>());
    }

    //flexible - can take a List of any subclass of Shape
    public void getShapeFrom(List<? extends Shape> l) {
        //  because the upper bound of list l is Shape, l is always a valid source for Shape instances
        Shape s = l.get(0);

        //  l.add(new Shape());
        //  ...will not compile, the type of l may be List<Circle>. Shapes are not all Circles
    }

    // Can add and get, but not very flexible - the method is limited to accepting Lists of type <Shape>
    public void testPutAndGet(List<Shape> l) {
        Shape s = l.get(0);
        Drawable d = l.get(0);
        l.add(new Shape());        
        l.add(new Circle());
    }
AddThis Social Bookmark Button

Maven License Plugin – open source just got a little bit easier

January 23rd, 2009 Nick Posted in musings, random, rants and opinions | 1 Comment »

Isn’t it nice when once in a blue moon somebody comes up with an innovation which makes your life just that little bit simpler – one of those little things which you soon take for granted, but you’d miss immediately if it was not longer there. In this case, it’s the Maven 2 plugin which automatically updates your source files with the appropriate license details

Maven License Plugin

Until now this was an annoyingly manual task which was just not quite annoying or time consuming enough to merit spending time automating. It was one of those borderline annoyances which you plan to do something about, every time it bites you. However, in this case it is always the last action before cutting a release, when you’ve had a long hard day, the caffeine has worn off (and it’s a bit late for another dose, you’d never get to sleep) – you’re running on an empty tank and you’d really like to get out of the door. Over time these small tasks stack up and sap your energy.

That’s why this plugin is such a life saver. It does just what it says on the tin, took about 5 minutes to set up and get going – saving time the very first time I used it, even taking into account the minimal setup and configuration.

Every time I find a new plugin like this I’m reminded of some of the great things about maven – particularly the convention over configuration, which facilitates such easy sharing and reuse, and allows most features to ‘just work’. For sure, there is a learning curve associated with maven – but once you’re up to speed the benefit really shows.

AddThis Social Bookmark Button

Careful how you synchronize toArray()

January 21st, 2009 Nick Posted in java | No Comments »

This is a fuller version of the code snippit I submitted to the interesting thread on java synchronization issues on stack overflow

In general it can be tempting to assume too much thread safety when using synchronized collection classes.
It can be easy to think they somehow grant you more protection than they actually do, and forget to hold the lock between calls.

If have seen this mistake a few times:

 List<String> l = Collections.synchronizedList(new ArrayList<String>());
 String[] s = l.toArray(new String[l.size()]);

In the second line above, the toArray and size() methods are both thread safe in their own right, but the size() is evaluated separately from the toArray(), and the lock on the List is not held between these two calls. If you run this code with another thread concurrently removing items from the list, sooner or later you will end up with a new String[] returned which is larger than required to hold all the elements in the list, and has null values in the tail, which will quite possibly result in a NullPointerException eventually.

It is easy to think that because the two method calls to the List occur in a single line of code this is somehow an atomic operation, but it is not. The best way to fix this is to hold the lock explicitly :

 List<String> l = Collections.synchronizedList(new ArrayList<String>());

 synchronized(l) {
    String[] s = l.toArray(new String[l.size()]);
 }
AddThis Social Bookmark Button

Browser search bar integration for safari bookshelf

January 12th, 2009 Nick Posted in rants and opinions, web | No Comments »

For quite a while now I’ve been a subscriber to O’Reilly Safari bookself. It contains a lot of useful books on a wide range of technical and programming topics.

Although there is a good selection of material on the site, I haven’t really made the best use of it until now, since it has in general been less accessible than other web resources (it has just been easier to google for material than navigate to the O’Reilly site, log in, find the right page, search for books etc.). This devalued the whole Safari experience.

However, there is now a search bar plugin for safari (available from the tools page) which allows you to treat Safari as a search engine, and makes its contents available from the search box integrated with your browser toolbar. This innovation is the killer feature for Safari, in my opinion. Suddenly it makes the Safari content as accessible as the rest of the web. Suddenly, I don’t seem to have enough slots in my Safari bookshelf account any more, and the subscription fee seems quite reasonable.

AddThis Social Bookmark Button

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