Sunday, January 04, 2009

Java Webstart Demos with Terracotta enabled

For easy deployment, Terracotta enabled Java applications can also be launched via web start. There are certain issues to look out for but it's certainly possible. I wrote a small demo to demonstrate it.

Issue 1: Terracotta installation required on user's computer before running.

This is solved easily by downloading a Terracotta zip file and extract it to a known location on user computer. In my demo, I install it to $HOME/terracotta_ws.

Issue 2: Java Webstart applications don't allow modification of boot classpath.

Since you can't append or pre-append to boot classpath of the webstart VM, which Terracotta requires, you are forced to spawn an external JVM for your app. This is solvable by signing your jars with a keystore, that will allow your webstart app to spawn external process. This is a good blog showing how to sign your jars.

Note that only jars that are part of your main webstart GUI frame and its libraries are required to be signed. Jars that are part of your Terracotta applications are not required.

When I use "webstart app", I mean the control app that is downloaded and run by Java webstart.

Wehn I use "main app" or "TC enabled app", I mean the Terracotta enabled applications that are spawned in external processes by the "webstart app"

Issue 3: You can't declare your main application jars as part of resources to download in JNLP file.

The main reason is that Java Webstart obfuscates those jars and stores them in a cache with variable folder name. So your webstart app has to handle the downloading and installing the main app's binaries (zip file) to a known location. This is also doable. Take a look at the JNLP file I have:

<jnlp spec="1.0+" codebase="http://localhost:8080/webstartdemo"
<title>TC webstart demo</title>
<description>Demo of how to start Terracotta from webstart
<description kind="short">TC Webstart example</description>
<offline-allowed />
<j2se version="1.5+" />
<jar href="TCWebStartDemo.jar" download="eager" />
<jar href="ant-1.7.1.jar" />
<jar href="ant-launcher-1.7.1.jar" />
<jar href="miglayout-3.6.2-swing.jar" />

<property name="tcws.codebase" value="http://localhost:8080/webstartdemo" />
<property name="" value="" />
<property name="tcws.demo.list" value="sharededitor,mandelbrot" />
<property name="tcws.sharededitor.mainClass" value="demo.sharededitor.Main" />
<property name="tcws.mandelbrot.mainClass" value="mandelbrot.Main" />

<application-desc main-class="demo.MainFrame" />
<all-permissions />

From line 13 to 16, those jars are for the webstart app which will be downloaded automatically by java webstart. And those are the ones that need to be signed.
Line 25 indicates the main class of the webstart app.

From line 18 to 22, that is how I communicate to my webstart app (via system properies) about where to download Terracotta and the demos (Terracotta enabled apps). Each demo is a zip file which contains a tc-config.xml, a "lib" folder with all the jars it requires.

You can play with the demo here.

The webstart app Eclipse project can be checked out at SVN repo

Your main interests should be the 2 classes:

Enjoy the demos :)


Unknown said...

I am curious how does the JavaWebStart application know whether the libraries appended to the boot classpath are compatible with the local Java runtime.

I always thought that you must run a TC script to generate a bootclasspath jar containing an altered java.lang.ClassLoader class.

Have you moved away from this hack to a javaagent?

Any chance making the filtering (ignore class condition) section in the rewritten classloader configurable as the classloader throws a wobbler with obfuscated classes especially thoses using encryption techniques?


Unknown said...

Good question, the external process is called with TC script "dso-java" which takes arguments just like "java" command. You only need to provide it with a "-classpath" or "-cp" and the main class to run. That script will handle creating the compatible bootjar that matches with the Java runtime. See the code in DemoManager.getDemoRunnable()

Unknown said...

We're looking at javaagent for a better approach (there was even a demo with some progress that one of the dev guy put together). It's certainly on the radar. Regarding obfuscated classes, I'm not aware of anything for the moment.