Skip to main content

Trip and Tick 2: JooJ up your project page with a Web Start demo

Posted by evanx on July 20, 2006 at 4:55 AM PDT

This series kicked off with
Trip and Tick 1: Checking out a java.net project
.

So you're hosting your project on java.net, and you've uploaded some screenshots. Supoib!
The next step is putting a Webstart "Launch" button on your page, innit.
Oh and a screencast video thingy, see the upcoming Trip and Tick 3: The Movie
for that.

Since i'm too lazy to read the JNLP documentation, and to write a JNLP file
from scratch by hand, i'm gonna use those firefox goggles for starters.
Later we'll be forced to read
Deploying Software with JNLP and Java Web Start
and edit the JNLP XML by hand, when as expected, things don't work as expected right off the bat.

Using the goggles we quickly see that Netbeans has a JNLP tool, woohoo!
And a tutorial aptly named
Using Java Web Start in NetBeans IDE
which i followed as follows.

We go to the Update Manager, choose the Netbeans Update Center Beta.

nbupdate.png vspace=4 hspace=4 border=0 />

When in doubt press the OK button. Unfortunately the above screen does not have
an OK button, so we try the Next button.

nbupdate2.png vspace=4 hspace=4 border=0 />

We add the Netbeans Module for Java Web Start.

nbupdate3.png vspace=4 hspace=4 border=0 />

I think we should meet and greet this module!

nbupdate4.png vspace=4 hspace=4 border=0 />

Now we see a Java Web Start item in the menu when we right click on our project.
We enable this, and when we Run with Webstart, Netbeans generates our
JNLP file, woohoo! It even provides a JNLP designer for
for manipulating the file with the mouse, as you can see below. Oisome!

aptws.png vspace=4 hspace=4 border=0 />

As expected from years of experience with softwarez, it doesn't work for us the first time, D'oh!

We enable the Java Webstart Console
to see the exception, or just click on Details and select the
Exception tab. We see it's a security permissions problem with the application
trying to access system properties ie. command line options.
Probably preferences would also cause a security violation.
So i disable properties and preferences in the application.

wsconsole.png vspace=4 hspace=4 border=0 />

Trying again, there is a different error, ie. progress, woohoo!

wsconsole2.png vspace=4 hspace=4 border=0 />

Looks like the above security exception is caused by field.setAccessible() ie. reflection.

Let's try a different angle of attack which is to disable sandbox security, for now.
We do this by adding a security element with all-permissions
into our JNLP as follows. If you know how to provide limited permissions, but
not all permissions, eg. to allow reflection and "standard" stuff, but obviously not
local file system access, please post a comment.

jnlp-security-all.png vspace=4 hspace=4 border=0 />

But we get a "jar not signed" JNLP exception, as we see when we click on Details
and then the Exception tab.

not-signed-error.png vspace=4 hspace=4 border=0 />

For this to work we gotta sign the jar as detailed in
Web Start Developer's Guide,
which gives us the following keytool and jarsigner commands.
(Update. Kirill Grouchnikov's
"Signing jars for java.net Web Start applications"

provides a great tutorial on signing your jars.)

    cd /opt/java5/bin
    keytool -genkey -keystore <b>myKeystore</b> -alias <b>myself</b>
    keytool -selfcert -alias <b>myself</b> -keystore <b>myKeystore</b>
    keytool -list -keystore <b>myKeystore</b>
    jarsigner -keystore <b>myKeystore /aptframework/netbeans/dist/aptframework.jar myself</b>
    javaws <b>/aptframework/netbeans/aptframework.jnlp</b>

where the keytool commmands we do once only, to create our "keystore,"
and the jarsigner command we do to prep the jar prior to trying to web start it.

signjar.png vspace=4 hspace=4 border=0 />

Now we write a JNLP file for our web page, as follows.

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jnlp codebase="<b>http://jroller.com/resources/e/evanx/</b>"&gt;
  &lt;information&gt;
    &lt;title&gt;<b>AptFramework Demo</b>&lt;/title&gt;
    &lt;vendor&gt;<b>aptframework.dev.java.net</b>&lt;/vendor&gt;
    &lt;icon href="default"/&gt;
    &lt;offline-allowed/&gt;
  &lt;/information&gt; 
  &lt;security&gt;
     &lt;<b>all-permissions</b>/&gt;
  &lt;/security&gt;
  &lt;resources&gt;
    &lt;j2se version="1.5+" /&gt;
    &lt;jar href="<b>aptframework.jar</b>"/&gt;
  &lt;/resources&gt;
  &lt;application-desc main-class="<b>aptcomponent.common.ZViewContext</b>"/&gt;
&lt;/jnlp&gt;   

For going online, all that changes is the codebase, which is now
an http URL, rather than a local file.

* align="left" hspace="8" >
I found that the weblogs.java.net webserver transforms XML files somehow,
like our JNLP file, so that Firefox displays the XML rather than
launching Web Start. So we upload our JNLP file and our jar to jroller.com rather,
because that seems to work.

Now we can insert the JNLP link into our HTML web page as follows.

&lt;a href="http://jroller.com/resources/e/evanx/aptframework.jnlp"&gt;
   &lt;img border=0 src="http://javadesktop.org/javanet_images/webstart.small.gif"&gt;
&lt;/a&gt;

Which looks like

webstart.small.gif
(695k, unsandboxed, Java5)

which hopefully works for you!?

Addendum on Dependent Jar Resources

Kirill Grouchnikov's
"Signing jars for java.net Web Start applications"

addresses dependent jars, where these might be signed
by someone else, eg. activation.jar  et al signed by Sun. In this case,
you can't include these directly as jar resources in your JNLP.
As Kirill shows, the trick is to wrap them in their own JNLP, and list that
as the resource in your JNLP. I include such an example below, for completeness.

But if you have dependent jars that are signed by someone else eg. Sun,
then you gonna get an error because your jars are not all signed by the same
certificate, ie. yours. You can inspect the signing certificates et al, using the following command.
(Incidently, the following JavaDB jar isn't signed, but for the sake of this discussion,
let's pretend that it is signed by Sun.)

jarsigner -certs -verbose -verify /projects/aptframework/lib/derby.jar    

As Kirill shows, we can create a JNLP file for dependent jars which are signed
by Sun et al, as follows.

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;jnlp codebase="<b>http://aptframework.dev.java.net</b>" href="<b>javadb.jnlp</b>"&gt;
  &lt;information&gt;
    &lt;title&gt;<b>JavaDB jar</b>&lt;/title&gt;
    &lt;vendor&gt;<b>Signed by Sun Microsystems, Inc</b>&lt;/vendor&gt;
    &lt;offline-allowed/&gt;
  &lt;/information&gt; 
  &lt;resources>
      &lt;jar href="<b>derby.jar</b>"/&gt;
  &lt;/resources&gt;
  &lt;component-desc/&gt;
&lt;/jnlp&gt;   

where in this case, i'm gonna check-in dependent jars under the www
subdirectory of my java.net project, in which case the codebase is my
java.net project homepage.

And then in the resources section of our JNLP, we list dependent jars,
including those wrapped in their own JNLP file, as follows.

  &lt;resources&gt;
    &lt;j2se version="1.5+" /&gt;
    &lt;jar href="aptframework.jar</b>"/&gt;
    &lt;jar href="aptfoundation.jar</b>"/&gt;
    <b>&lt;extension href="javadb.jnlp"/&gt;</b>
  &lt;/resources&gt;   

Now i've just gotta update my demo to actually use JavaDB, eg. for an in-memory database :)

Related Topics >>