Eclipse Zone is brought to you in partnership with:

Steven has posted 36 posts at DZone. View Full User Profile

A system tray icon for monitoring Hudson with Eclipse RCP

01.23.2008
| 17863 views |
  • submit to reddit

Our team needed a system tray icon that indicates the status of the most recent build in Hudson. I decided to write a small application with Eclipse RCP which took me about a day.

Why Eclipse RCP? First, I didn't want to get involved with .NET. I only have the slimmest .NET knowledge and I didn't want to loose time by my lack of experience. Secondly, some of us have a Mac :-)

Thirdly, system tray icons can be added from the JVM. Java 6 supports it as does Eclipse Europa (3.3). I did a quick poll in our team and the majority wanted to avoid installing Java 6 on their machines. And some of us have a Mac :-)

So I ended creating my first application ever with Eclipse RCP. To get started I got the latest Eclipse release and followed the instructions to create a new RCP project here. Next I copied the system-tray-related code I found here.

That got me started. The first thing I did was obtaining some interesting icons to indicate a success and failed build. I found them here.

Plugin development (Eclipse considers an RCP application as a kind of plugin) in Eclipse is very intuitive, the Eclipse GUI makes things easy enough, like launching the application from Eclipse. Obviously debugging the application is very easy as well.

Based on the generated classes I've added all my logic to the ApplicationWorkbenchWindowAdvisor class. The first annoyance I ran into is Eclipse's threading model. Hudson has an RSS feed that contains the status of the latest build. I wanted to start a new thread to regularly check the RSS feed for updates.

But you cannot start a new thread and call Eclipse GUI components from it. Instead you have to call the org.eclipse.swt.widgets.Display#asyncExec(Runnable) method to execute code in a separate thread. But that's not all. I first implemented my Runnable class like this:

Runnable checkFeed = new Runnable() {
    public void run() {
        while (true) {
            // check the feed
            try {
                Thread.sleep(30 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

window.getShell().getDisplay().asyncExec(checkFeed);

This however did not work out since the endless while loop blocks all GUI activity, including the popup menu when right-clicking on the system tray icon.

I had to stop blocking this thread, so I implemented the Runnable class as follows:

private long lastFeedCheck = 0;

private void launchFeedCheckingThread() {
    Runnable checkFeed = new Runnable() {
        public void run() {
            long now = System.currentTimeMillis();
            if (now - lastFeedCheck < 30000) {
                // sleep a little while to avoid being a CPU hog
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // re-schedule this Runnable instance
                if (!window.getShell().getDisplay().isDisposed()) {
                    window.getShell().getDisplay().asyncExec(this);
                }
                return;             
            }
            try {
                // check the feed
            } finally {
                // update the timestamp variable to delay the
                // next feed check with 30 seconds
                lastFeedCheck = System.currentTimeMillis();
                // re-schedule this Runnable instance
                if (!window.getShell().getDisplay().isDisposed()) {
                    window.getShell().getDisplay().asyncExec(this);
                }
            }
        }
    }

    // launch the feed checking thread for the first time
    window.getShell().getDisplay().asyncExec(checkFeed);
}

This effectively frees up the thread with GUI activity responding promptly. While the RCP application behaved nicely when launched from Eclipse I ran into trouble when exporting the stand-alone application.

In Eclipse, exporting an RCP application is pretty straightforward. First, you have to create a 'Product Configuration' file (New -> Other -> Product Configuration). Here you can provide deployment options, like adding additional Eclipse plugins.

This worked fine until I added two libraries to the application: rome.jar and jdom.jar. I'm using them to read the Hudson RSS feed. I first added them as a project library in Eclipse as you would do in a regular Java project.

This however is not enough to have them exported. I tried adding them to the build.properties file under the Extra Classpath Entries section. This solved the error that previously occurred while exporting.

But the JARs still weren't included in the exported application. Unable to find another work-around I decompressed the content of both JARs in the root of the RCP project and included them for export in the build.properties file (see screen shot). This effectively included the required classed in the exported application :-)

Overall my first project in Eclipse RCP was a breeze. The Eclipse API is somewhat crowded but still intuitive to program with. The fact that the Eclipse classes have the source code attached makes things easier as well.

If you want to monitor you own Hudson server from your system tray check out the source code (Eclipse 3.3 plugin edition required) and Windows binaries.

Happy coding!

AttachmentSize
HudsonTray-win32.zip12.11 MB
HudsonTray-source.zip685.13 KB
ApplicationWorkbenchWindowAdvisor.java6.93 KB
Published at DZone with permission of its author, Steven Devijver.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Steven Devijver replied on Thu, 2008/01/24 - 4:45am

Hey Paul, I just downloaded all files without problems. Can you try again please? Do you get an error message? Which one? Steven

Toby Weston replied on Sat, 2008/09/13 - 10:33am

Hi, Great article, did you have sucess running on Mac with this? I'm having problems with notifications (balloon help) with something similar.

 The SWT snippet (http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet225.java?view=co) just plain don't work for me on Mac, any ideas?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.