WebStart and 29 seconds
I've been using Java WebStart as an application deployment tool for, well, several years now and it just gets better and better. In practice, I haven't looked at the Java WebStart details, like JNLP file contents and such, since my first deployment short off adding new "component" descriptions and the like, as described in the blog entry JXTA, WebStart and You.
Well, it does pay to periodically revisit "what you (think you) know" and tune accordingly. As such, following are some findings I uncoverred based on real world, end user Java WebStart deployments of which the gory details are captured via the relevant developer list.
Firstly, the application used for this study is MyJXTA, a reference JXTA application. MyJXTA optionally relies on a number of jars for various features. By leveraging Java WebStart, one can readily add resources (aka component applications), new invocations of the application are (optimally) refreshed and overall application instantiation is reduced via marking optional resources as "lazy load" (or "not eager"). All great stuff, but, MyJXTA use cases, as deployed, where exhibiting 2 problems:
- slow startup
- applications were not being updated upon restart
Before diving into hackary mode I opted to establish some baselines, take application inventory and map out what the desired runtime behaviours should be, knowing that I know. Here's the take away:
- of the 30+ jars, only one should be required to be marked as eager
- for the default runtime, only 8 jar downloads, in total, should be required
- subsequent applications executions should pull down only modified jars since the last run
Further, I did a bit of baseline benchmarking using my work system to measure first user interaction and application start. The first user interaction in this case is a Java WebStart dialog notifying the invocation of an unsigned jar whereas the application start event was the MyJXTA configuration dialog, the application proper. As such I measured, on average, as baseline time of 36s for first interaction and 51s for application start. My network connection is quite high so for the casual home user these numbers are likley worse. Not good. Further, the fact applications weren't being updated was very troubling.
With this information in hand, I hooked up with Thomas (Mr. WebStart) who patiently offered suggestions and the like. We validated that all the jars were indeed downloading, for the first invocation. Upon deeper investigation the root cause was that Log4J was looking for a "log4j.xml" resource in the anonymous package. The Java WebStart class loader couldn't resolve the resources from the activated jars and as such proceeded to download all remaining jars as described in the JNPL files in quick succession looking for the "log4.jxml" resource. The solution for this situation was to add "packaging" information to the JNLP file that, in turn, provides the Java WebStart class loader with java package information for the associated jar such that jars need not be pre-fetched only to find out the resource wasn't in the jar to begin with. Here's an example:
<package name="net.jxta.myjxta.*" part="myjxta" recursive="true"/>
<jar href="lib/myjxta.jar" main="true" part="myjxta" download="eager"/>
In adding the correct package notation I was able to reduce the actual downlaod down to 5 files that shouldn't be required. One of the jars has a class in the anonymous package and as such is not addressible and in order to include it with MyJXTA it was needed to be marked, unfortunately, as eager. OK, 2 required jars, not too bad as I can live with that, but I had 4 additional jars there were being pulled down. Upon bringing this up with Thomas it turned out there is/was a Java WebStart bug whereby the first jar as registered within a component JNLP file was always pulled down. I expect that issue is now fixed and a work around I flirted with was to simply generate an "empty" jar and register it as the first within the respective JNLP files.
Life was now much better and I was showing download times of 26s and 35s accordingly. Hmmmmm, a roughly 50% improvement in performance was fine but I felt there had to be more ... but I needed to figure out why subsequent runs of the application did not trigger the relevant jar updates. Long story short, I was/am hosting on an HTTP Server that did not provide the Java WebStart (client) application with enough file meta data to which it could deduce a resources' "staleness." To test out this assertion I deployed MyJXTA on a "simple" HTTP server and upon restart the expected behaviour occured, that being only changed application resources (jars) were pulled down.
Excellent! I was feeling pretty good about all of this but that 26s and 35s startup metric still bothered me.
ponder ... ponder ... ponder
Given I now had another optimally configured HTTP server to work with, one that provided Java WebStart with all the needed file data (eg Content-Length, Modified-Date, etc) I opted to check into Pack200 ... and was simply blown away by the outcome.
Firstly, the hosting environment needs to be able to handle the pack200 optimization requests. Fortunately, the test system a colleauge has provided is already pack200 ready. Next up, I augmented the nightly build process to additionally build packed jars, which reside right next to their unpacked source. No real problem there short a bit of sh/ant tweaks.
Now, upon deployment, I ran a test again and this time I (repeatidly) came up with 7s and 18s respectively.
An overall 5x savings in performance. Life is now good ... except I haven't fully migrated to the preferred HTTP server. In time.
The remaining opportunities for improvements that I have yet to address include:
- CA sign the jars
- get rid of the anonymous package dependencies
- deploy to a Java WebStart and Pack200 friendly HTTP server
We need to CA sign our jars anyways so the only real issue there is process and time. Re-packaging and exhisting application shouldn't be terrible but it does take time. Redeploying to the preferred server does require a bit of process overhead that will be addressed in time.
This blog is late, terse and not necessarily a good/easy read. On the other hand it is based on real world experience and to that end I hope it helps others in kind.
Lastly, mad props to the Swing folks! Well deserved. Go big!
in my ears: The Cyrstal Method/Community Service/Roadhouse Blues