Skip to main content

Modularizing java.net Web Start applications

Posted by kirillcool on August 7, 2008 at 1:25 PM PDT

I have blogged about signing java.net-based Web Start applications and splitting the JNLP files to accomodate jars signed by different certificates. So what happens when you have multiple projects on java.net and want to reuse some of the binaries between their WebStart applications?

I have a few desktop-related projects on java.net, and one of them (Rainbow) is an application that uses binaries from three other projects. In the past Rainbow's WebStart applications would need to be updated and re-signed every time the dependent libraries were updated. This was a time-consuming process, as i would sign the jars for the original projects (for their own WebStart demoes), copy the original jars to Rainbow's www folder and sign them there with another certificate.

Fortunately, the technique in the previous entry can be extended to JNLP files hosted on different java.net projects, with each dependent project exposing its jars in a separate JNLP file, and the main JNLP file referencing the dependent JNLPs. Here is the relevant JNLP file from one of the dependent projects (Flamingo component suite):


<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="https://flamingo.dev.java.net/webstart/"
href="flamingo-all.jnlp">
<information>
  <title>Flamingo jars</title>
  <vendor>https://flamingo.dev.java.net/</vendor>
  <offline-allowed/>
</information>
<offline-allowed/>
<security>
  <all-permissions/>
</security>
<resources>
  <property name="jnlp.packEnabled" value="true"/>
  <j2se version="1.6+" />
  <jar href="flamingo-tst.jar"/>
  <jar href="flamingo.jar"/>
  <jar href="svnkit.jar"/>
  <jar href="batik/batik-all.jar"/>
  <jar href="batik/js.jar"/>
  <jar href="batik/xerces_2_5_0.jar"/>
  <jar href="batik/xml-apis.jar"/>
  <jar href="batik/xml-apis-ext.jar"/>
</resources>
<component-desc/>
</jnlp>

Note that i'm using the new jnlp.packEnabled property supported by JDK 6u10 that will pick the pack200 binaries if they are available. Also note that this JNLP only enumerates the jars - it doesn't have the main-class.

How does the main JNLP look like?


<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="https://rainbow.dev.java.net/webstart/"
href="rainbowSvn.jnlp">
<information>
  <title>Rainbow SVN demo</title>
  <vendor>https://rainbow.dev.java.net/</vendor>
  <description>Rainbow demo - Subversion SVG explorer</description>
  <description kind="short">Rainbow demo - Subversion SVG explorer</description>
  <offline-allowed/>
</information>
<offline-allowed/>
<security>
  <all-permissions/>
</security>
<resources>
  <property name="jnlp.packEnabled" value="true"/>
  <j2se version="1.6+" java-vm-args="-Xmx256m"/>
  <jar href="rainbow.jar"/>
  <jar href="lib/filters.jar"/>
  <jar href="lib/jxlayer.jar"/>
  <extension name="substance-all"
href="https://substance.dev.java.net/webstart/substance-all.jnlp"/>
  <extension name="flamingo-all"
href="https://flamingo.dev.java.net/webstart/flamingo-all.jnlp"/>
  <extension name="substance-flamingo-core"
href="https://substance-flamingo.dev.java.net/webstart/substance-flamingo-core.jnlp"/>
  <extension name="syntaxpane" href="lib/syntaxpane.jnlp"/>
</resources>
<application-desc main-class="org.jvnet.rainbow.RainbowSvnViewer" />
</jnlp>

I've highlighted the dependent JNLP files in red. Now i don't need to do anything when i update the jar files in the dependent projects. Once those jar files have been updated and re-signed, the main Rainbow application will automatically use them.

There is one more important issue to address here - referencing JNLP files that use signed jars. Before, all jars in the Rainbow WebStart application were signed with the same (self-signed) certificate. There was only one security warning window shown to the users. Once it was accepted, the application was launched. Now that we have multiple JNLPs (with each having its own signed jars) we are degrading the user experience - WebStart is going to show multiple security warning dialogs if the signed jars are using separate keystores.

A solution involves using one keystore for all your projects and sign all the exposed jars against that keystore. WebStart will recognize that even though the JNLPs come from different projects, the jars are signed with the same certificate. The decision on where should that keystore be is yours. If you have a primary root project and all other projects are subprojects of that root, place you keystore in the root project. In my case i'm using the PushingPixels project for managing the single keystore. Even though it is not a parent project of the Rainbow dependencies (in java.net terms), WebStart is showing only one security warning window. This way the jars are signed under one project, but hosted under another one. As long as your users trust you as the owner of both projects you shouldn't have problems in using multi-hosted jars in your signed java.net WebStart application.

Related Topics >>

Comments

If signatures are required: Why even bother with all the JNLP? Much simpler is to provide an href link to: pwned.exe If the application cannot run within the Java sandbox, unsigned, then it is not truly a "Rich Internet Application" Please, don't let WebStart become known as virusware!

That's great, mbien :-) Thanks.

yes exactly, works pretty well (even for applets); https://jdk6.dev.java.net/testProperty.html hint: One of the javafx NetBeans modules (I don't remember which one) has pack200 compression ant scripts. I use it in the build to self-sign + pack everything I even had a target which automatically uploaded the result to the java.net project documents and files section (but this is off topic). Doing this in cmdline is a pretty boring task ;).

"... JDK 6u10 that will pick the pack200 binaries if they are available. ". Can you elaborate on that? Does this mean that it allows me to put *.pack.gz stuff on java.net and pack200 will work without requiring a specific servlet (that of course I can't run on java.net)? Thanks.