December 2004 archive

Java Web Start 1.5

The Java Network Launching Protocol (JNLP), commonly known as Java Web Start, is some very cool technology. In my opinion, it hits a sweet spot between web applications and local applications:

  • Software is run locally on the client machine. JNLP is supported on every platform that Sun’s Java Runtime environment is available, including Linux, Windows, and Mac OS X.
  • The software can be updated on the remote server, and it is updated locally as soon as it is next run.
  • Desktop integration is possible, meaning that the user of the software has a nice double-clickable application shortcut on their desktop, start menu, applications folder, or wherever you would store such a thing in Linux.
  • New in Java 1.5^H^H^H5.0 – file associations can be specified in JNLP files, meaning that I can open a “.whatever” file with the Whatever Java Web Start application by clicking it. Cool!

So, basically JNLP has some of the advantages of Web applications (immediate upgrades available, doesn’t need to be rolled out by network administrators [whether this is really an advantage is questionable]), and some of the advantages of desktop applications (run locally, quick to run, shortcuts and file associations). Cool.

However, the changes to JNLP in Java 1.5 are somewhat poorly documented. I’ve discovered three tidbits of information that I believe are pretty useful, so I’m going to share them with you.

First of all, I wanted my users to know that by using Java 1.5 they’re going to get some additional functionality (file associations), but my application still runs in Java 1.4. I updated my web start launch page to check for 1.5.0 (thanks to Sun’s documentation), and then made it link to my download page with some useful text if they don’t have 1.5. However, if the user went to the download page when running Java 1.4, it did not upgrade to Java 1.5 – it saw that Java Web Start was available, and launched the application.

Adding a #Version tag to the download page fixed this, forcing an upgrade to 1.5.0:


<!--
Automatically installs Java 1.5.0 and runs the PDA application with
Java Web Start.  The addition of the #Version section on the object's
codebase will cause an upgrade to JRE 1.5.0 even if the user already
has a Java Runtime installed.
-->
<object
  codebase="http://java.sun.com/update/1.5.0/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"
  classid="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284"
  height="0"
  width="0">
    <param name="app" value="http://yoursite.com/app.jnlp">
    <param name="back" value="true">
    <!-- Alternate HTML for browsers which cannot instantiate the object -->
    <a
        xhref="http://java.sun.com/j2se/1.5.0/download.html"
        mce_href="http://java.sun.com/j2se/1.5.0/download.html">
          Download Java Web Start
    </a>
</object>

So, now my users had the option to upgrade to Java 1.5. Some of them might even do it. Now, how does one get the file associations to work? At the time I was looking at it (and still as I write this), Sun’s getting started guide is grossly incorrect when discussing the <association> tag in the JNLP file. The getting started guide also does not explain what changes to make to your application to get it to actually open the file when you double click on it.

The first part was easy – Keith Lea already documented the problem, and Google lead me straight to it. Add an <association> tag to your JNLP file, like this:

<association mime-type="application-x/some-mime-type" extensions="ext"/>

One step closer! Now I can click on my files and the application launches, but it doesn’t do anything with the file I opened. I took a guess that it was probably passing the filename in through the command line parameters, and put some message boxes into my main function. Sure enough, that’s how it’s being done. I’m being passed two options: -open, and then the filename to open. The following code in my main function dealt with this:


// Handle JNLP association command line argument file opening.
// Format: '-open' 'path-to-file'
boolean openFlag = false;
for (int i = 0; i < args.length; i++)
{
    if (openFlag)
        openPath(args[i]);

    if (args[i].equals("-open"))
        openFlag = true;
    else
        openFlag = false;
}

Now I’m happily taking advantage of the new features in JNLP 1.5, without forcing my users to upgrade if they don’t want to. It’s a happy day.