users@glassfish.java.net

Calling all users of Java Web Start support for app clients in GlassFish

From: <glassfish_at_javadesktop.org>
Date: Mon, 28 Jun 2010 18:22:14 PDT

[i]Warning[/i] - long post but if you are in the target audience please read it and respond!

We are working on a feature to allow developers to customize the JNLP document which GlassFish generates for launching an app client. We have had specific requests to allow users to change the icon and splash screen images and the title used for the download progress box. (GlassFish has allowed those customizations in a bit of awkward way a while ago (the <vendor> element inside the <java-web-start-access> element in sun-application-client.xml; see this earlier posting).

I wrote up a proposal (http://wiki.glassfish.java.net/Wiki.jsp?page=Gfv31JNLPCustomization), hoping to get comments from our users who have used the Java Web Start feature (and I know you are out there!). But we got no responses. So I'm trying again with this posting. I realize this is on the long side but please stay with it. I really want to hear what people in our community have to say about this.

Users have also requested the ability to add JARs - especially for native libraries - and to customize the VM settings set in the vm-args element of the <java> element in the JNLP document.

For a number of (we think) good reasons, GlassFish does not actually write out the generated JNLP file anywhere. It computes the JNLP document for an app client every time the application containing the app client is loaded. So it's not quite as simple as letting developers edit the generated file on the disk which has its own problems.

So given that GlassFish will most likely continue to compute the JNLP at load-time, here are two quite different approaches we could take:

[b]Approach 1:[/b] Enhance the glassfish-application-client.xml descriptor (used to be the sun-application-client.xml file) so a developer could explicitly tell the splash screen images and and icon images as well as the vendor. We could also add <vm-args> and a repeating element for <nativelib>. So part of the glassfish-application-client.xml descriptor might look like this:

<glassfish-application-client>
...
  <java-web-start-access>
    <vendor>My Company, Inc.</vendor>
    ...
    <vm-args>...</vm-args>
    <nativelib href="path/to/nativelib.jar" .../>
    <nativelib href="path/to/otherlib.jar" .../>

This is appealing because it's pretty simple. You, as a developer, would have to edit only one file to reflect whatever customization you wanted to accomplish. One potential drawback is that we would need to add elements to the descriptor format for all the items that developers should be allowed to customize and write the code in GlassFish to process them. If developers wanted to customize other things, that just would not be possible until we changed GlassFish again to allow it.

[b]Approach 2[/b]: Adopt a more general but, therefore, more complicated approach. This will seem really appealing and simple at first, but please read far enough to see the issues with this idea.

The idea here is that in the descriptor you would point to where the JNLP file is, using something like this:

<java-web-start-access>
    <jnlp-doc>xxx/mySettings.jnlp</jnlp-doc>

The value xxx/mySettings.jnlp points to a JNLP file that you had packaged inside the app client JAR (more about this later). You would write this file using the standard structure of a JNLP document, but you would only have to provide the values you wanted to customize and provide the surrounding elements so your customizations are in the right place in the JNLP document's structure. As an example, if you needed to specify different native libraries for different end-user platforms, your document might look like this:

<jnlp>
  <resources os="Windows"/>
    <nativelib href="lib/windows/corelibs.jar"/>
  </resources>
  <resources os="SunOS" arch="SPARC">
    <nativelib href="lib/solaris/corelibs.jar"/>
  </resources>
</jnlp>

[b]How GlassFish Would Combine the JNLP[/b]

Please see the one-pager linked above for the details on this. Basically, there is some content GlassFish would completely determine, some it would let you specify but if you don't it will provide defaults, and some that it would merge its generated content with yours.

GlassFish sets the codebase attribute in the <jnlp> element in a way that corresponds to the top-level of the EAR you deployed. In Approach 2, therefore, GlassFish resolves the href attribute values in your custom JNLP relative to the top of the EAR.

[b]Some Complications[/b]

So far so good. But what happens if your JNLP refers to another JNLP document using <extension href="other.jnlp"> ? The JNLP spec says that all relative hrefs are resolved against the codebase of the current JNLP document. I mentioned earlier that the codebase corresponds to the top level of the EAR. That means that you would need to package other.jnlp at the top-level of the EAR. Or if your href was "yyy/other.jnlp" they you would need to package other.jnlp in the yyy directory in the EAR. Things are getting messy because you put your original custom JNLP into the app client EAR but you need to put your other.jnlp file into the EAR itself.

One solution for that would be to allow (not require) references from your JNLP to other JNLPs to somehow specify the JAR within the EAR that holds the referenced JNLP file. Something like <extension href="x/y.jar!z/other.jnlp"/> which is very close to the way we can specify paths to an entry inside a JAR file in normal URLs. So in this example GlassFish would look in the JAR x/y.jar for the entry z/other.jnlp.

(By the way -- don't try this notation in a normal JNLP file served by a normal web app servlet. It won't work -- at least not when I tried it last week. This would work with GlassFish because it uses a special-purpose Grizzly adapter to respond to requests related to app client launches using Java Web Start.)

[b]Another Complication - Security vs. Flexibility[/b]

Ever since GlassFish first provided automatic Java Web Start support for app clients, the system has guarded against rogue users trying to download arbitrary parts of an application. A malicious user could conceivably look at the URLs for the downloaded JARs, images, and JNLPs and change them to try to fetch other files. GlassFish, in the current and past implementations, knows what JARs the app client needs and will download only those JARs (and, of course, the JNLP files which GlassFish itself generated).

Ideally, we'd continue that practice. GlassFish would scan your custom JNLP file(s) to know what JARs, images, and other JNLPs it needs to serve and would not serve anything else.

Bill Shannon, one of our architects, pointed out the following trade-off though. You could write an app client knowing your users would launch using Java Web Start. That client's Java code might need to read other resources - say a data file - from your application by constructing a URL or URLConnection object. In normal (non-GlassFish app client) Java Web Start applications this would work if your client used the JNLP API to get the current codebase and then combine that with the relative URL. (The Java Web Start runtime might do that automatically if you just use the relative URL, as happens inside applets. I'm not sure about that.) Anyway, the point is that your client could compose a URL to something that does not appear in your JNLPs. Today, GlassFish would not serve that file because it did not appear in the JNLPs it had scanned.

Again, two possibilities:

1. Relax the security. The Grizzly adapter would then serve any content from the EAR. (We don't really like this option.)

2. Keep the security. You, as the developer, would have to access the data file using some other technique, for example packaging the data file into a web module and using the web module's path to retrieve the data file.

[b]A Plea for Feedback[/b]

Please PLEASE take some time to read this, think about it, and let us know what you think. Please post your comments as responses to this posting.

Many thanks in advance.

- Tim
[Message sent by forum member 'tjquinn']

http://forums.java.net/jive/thread.jspa?messageID=476230