Web Start Network: Web Start News - Web Start F.A.Q. - Web Start Forum - The Saturn Times - Lopica - Rachel - Apollo
Lopica Logo
All Things Web Start - Web Start Paradise - Web Start Encyclopedia - Web Start Tools
What's On? | Web Start News | Web Start F.A.Q. | Web Start Forum | The Saturn Times | Web Start Services | Web Start Links | Download | Lopica @ Sourceforge

Unofficial Java Web Start/JNLP FAQ

Overview

This FAQ complements Sun's official Java Web Start FAQ page and aims to provide you with information that is not included on the official page for whatever reason. If you just started with Web Start, please check Sun's Official Java Web Start/JNLP FAQ third-party link page first.

I invite you to share your insights, comments, suggestions, or corrections. Please send them to the lopica-talk mailinglist (Subscribe/Unsubscribe) or send a private email to gerald@vamphq.com (Gerald Bauer) or post your insights at Sun's Java Web Start and JNLP forum third-party link. The Unofficial Web Start FAQ is a living, growing list of answers, not just a publish-and-forget-it static dead-tree booklet, help to improve it.

Questions and Answers

What's new?

General

Web Server Setup

Installation and Troubleshooting

Resource Loading

JNLP Descriptors (aka Start-Up File)

Libraries (JSSE, JCE, JAAS, etc.)

Security, Signing, Sandbox

Web Start Extensions

J2EE Troubleshooting

Misc

Links

General

Q: What does the support of Web Start in Java 1.4 look like?

Web Start is bundled with Java 1.4.

On Windows, Web Start is installed silently during the installation of the Java 1.4. Look for a Web Start icon on your desktop. There will also be an entry for Web Start in the Start --> Programs menu.

On Solaris and Linux, the installation script for Web Start is contained within a zip file that you can find in the jre directory of the JDK (or in the top level of the JRE). Move the zip file to a location where you would like to install Web Start. Sun recommends that this location be outside the JDK or JRE directory structure. Unzip the file and run the install.sh script to install Web Start.

Be warned, if you install Java 1.4 Beta 2 it will erase the content of your Web Start cache. You have to download all apps again. Note, this behavior is fixed starting with Web Start 1.0.1_02.

Milestone Expected Date
Beta 2 (aka Beta Refresh) early September 2001
Beta 3 end of the year 2001
Release Candidate (RC) 1 beginning of 2002
Final Release first quater of 2002 (Q1 2002)

Sun released Java 1.4 in mid-February 2002 as scheduled for Linux, Windows and Solaris.

Q: Can Web Start update itself?

Web Start has an update detection mechanism that can inform the user when a new release is available. At the moment the installation is manual. However, Web Start itself (without a JRE) is expected to be a download of 400k or less. Web Start already supports automatic upgrading to newer versions of JREs.

Q: Can I use Web Start for command line/batch apps?

Support for command line/batch apps is currently limited. You can launch apps from a command prompt/shell. Example:

javaws http://java.sun.com/apps/draw.jnlp

However, you cannot pass in arguments for your app on the command line as javaws only takes a single URL as an argument and ignores the rest.

If you want to pass in arguments to your app, you have to add them to the start-up file (aka JNLP descriptor) using <argument> or <property> elements. Nothing is wrong with "hard-coding" your arguments in the start-up file (aka JNLP descriptor) as long as your arguments don't change.

If your arguments are not known in advance or change from time to time, there are a couple of workarounds to pass your arguments along to your app.

A simple workaround is to create a servlet that takes in your arguments as parameters in the URL (e.g. http://localhost/apps/notepad.jsp?dir=c:/carrie/chap1/shower.txt) and adds them to the startup file (aka JNLP descriptor) that it sends along to Web Start. This workaround requires a web server.

(One trick is to make sure not to include the href attribute in the JNLP file that your servlet sends back to Web Start. This will tell Web Start to disable the update check on JNLP files, and Web Start will not treat each new JNLP file as an application update - only updated jar files will.)

A more esotereric workaround that doesn't require a web server is creating your own JNLP client that allows you to pass along your arguments to your apps. That sounds harder than it is. Building a stripped down JNLP client (e.g. no installer, no applets) using one of the two open-source client as a start takes probably just a couple of days and should be sufficient for in house usage.

A more sopisticated workaround that doesn't require a web server and that doesn't require you to replace Web Start is wrapping your own executable around javaws that takes your passed in arguments plus JNLP URL and looks up the original in the cache and patches it or adds a new one to the cache that it passes on to javaws to start up the app using your arguments.

The next step would be to create another executable that wraps your wrapper to make a command-line call look like as nothing had happened. Example:

javawsex http://jakarta.apache.org/ant.jnlp jar javadoc crossref
javawsex http://java.sun.com/apps/notepad.jnlp c:/carrie/chap1/shower.txt

becomes

ant jar javadoc crossref
notepad c:/carrie/chap1/shower.txt

Q: Can I use Web Start for Intranet apps?

Yes, Web Start is well-suited for Intranet apps. Note, that you can also use file:// URLs to access the local file system. If you use file:// URLs you need to use file:/// because file:// doesn't work. The third slash is required for the left out host name. Example:

javaws file:///c:/sandbox/venus/startup/hazel.jnlp

In case your path to the .jnlp file contains spaces, enclose the path in double quotes. Example:

javaws "file:///C:\Program Files\Java Web Start\
  .javaws\cache\http\Dlocalhost\P80\DMclient\AMdemo.jnlp"

Q: Is Web Start available for Macintosh?

Web Start ships with Mac OS X 10.1. You can see it with your own eyes at http://developer.apple.com/java/javawebstart/ third-party link

Note, that Web Start is not available for download as a separate package. It is only available with Mac OS X 10.1 or later as a bundle.

Another option is alive and kicking OpenJNLP lead by Kevin Herrboldt at http://openjnlp.sourceforge.net third-party link which works on all platforms including Mac OS 9 and other JDK 1.1 platforms.

Q: Does Web Start support downloading jars using FTP?

Web Start cannot handle FTP connections because it depends on HTTP headers for determining things like last-modified date. FTP returns no such headers.

The JNLP spec explicitly limits JNLP to the HTTP protocol.

Q: How can I use Web Start and Jini together?

The following is a short excerpt from the book "A Programmer's Guide to Jini Technology" by Jan Newmarch. The full chapter is available online at http://pandonia.canberra.edu.au/java/jini/tutorial/JNLP.xml third-party link

Jini and JNLP Comparison

On the face of it, Jini and JNLP appear to occupy similar spaces in that they both allow code to be migrated to a client machine and to execute there. The following table summarises some of the differences and similarities

Jini JNLP
downloads a service downloads an application
a client must be running to request a service a browser must be running which calls a helper to start the application
each service looks after itself, independently of any clients each JNLP file specifies all required parts of an application; if any part changes, the JNLP file must be updated
the client may need to know the location of a lookup service, but not of any service the user of a JNLP application must know the URL of the JNLP file
no generic client generic JNLP helper

Combining Jini and JNLP

If a user does not have the client-side of a Jini application installed, then they cannot make use of Jini services. Here is where JNLP can help, by allowing a user to download an application that can run as the client. The user only needs to know a URL for this, and finding URLs is a common experience for most users nowadays. Corporate Web sites, Web search engines, portals and so on are all mechanisms used to find interesting Web sites and download information.

The converse question is: if JNLP is used to find an application, what is the value of Jini in this? The answer to this lises in the distributed management of Jini services. Suppose a JNLP application relies on a number of components put together, say as a collection of packages. The JNLP file has to specify the location of every one of these packages. If one of the packages changes, then the JNLP file has to be updated. It gets more complex if one of the packages changes to become dependant upon another new package: that new package has to be added to the JNLP file. In other words, management of a JNLP application has to be centralised, to the manager of the JNLP file.

Jini, on the other hand, lets every package/service be managed by its own manager. If a Jini service changes implementation, then it can do so without any external consultation, and just re-registers the new implementation with Jini lookup services. If a service changes to use another service, it does not need to inform anyone else about this change. A Jini client does not need to know how services are implemented ot even where they are located.

Jini is not quite management-free: a client may need to know where lookup services reside. On a local network a client can use multicast to locate lookup services, but outside of this local network clients will need to used unicast to find lookup services at known locations. This is still an improvement: Jini lookup services are relatively stable, persistent and stationary services, whereas the services themselves may be transient or unstable.

The combination of Jini and JNLP works like this:

  1. A user finds the URL for an application
  2. The user downloads the JNLP file which is executed by the JNLP helper
  3. The helper downloads the application's jar files, and runs a Java runtime engine with these jar files
  4. Properties are set in the JNLP file for Jini lookup services, so the application can locate its required Jini lookup services at runtime
  5. When the application needs a service, it finds it from the Jini lookup services and uses it
  6. If the service needs to make use of other services, then it can perform its own search for them, without the knowledge of the application

Q: Can I use Web Start to deploy server apps?

Web Start is designed for rich desktop apps and, therefore, has currently limited support for command line apps or mission critical, 24x7x365, always-up, high performance daemons serving thousands of customers simultaneously.

If you want to deploy web apps consider using Web Archives (.war).

An installation service for Java Daemons is also in the works as Java Specification Request (JSR) 96. Check out JSR 96 - Java Daemons at http://www.jcp.org/jsr/detail/96.jsp third-party link. The stated goal is to supply a small container framework for developing and deploying independently running services in order to fill the gap caused by different handling of existing native platfroms.

(Status: Expert Group Formed - Yes, Public Review Underway - No, Community Draft Published - No, Proposed Final Draft Published - No)

Q: Can I use Web Start to deploy apps to mobile devices (J2ME)?

Web Start is designed for rich desktop apps (aka resource hogs) requiring Megas of disk space and very likely doesn't fit on your Java phone unless you attach a Giga hard disk somehow.

If you want to deploy apps to mobile devices consider using MIDlets.


You can try the SavaJe XE operating system for StrongARM devices. SavaJe includes the J2SE 1.3, so it could work with Web Start. You can download a trial copy of SavaJe XE from http://www.savaje.com third-party link

- Marco Maier


A goal for OpenJNLP is to run on PDAs.

OpenJNLP has been split into a JNLP-launching library and a separate app/GUI. Swing and the GUI have never been required to use OpenJNLP launching, and it's even easier to use as a standalone library now. The OpenJNLP library is currently 48KB in size, should fit on a PDA easily even with the XML parser. Packaging is simplified as well, requiring just the library, SAX2 and NanoXML in the classpath. If you want the full app/GUI you add the app jar.

- Kevin Herrboldt (author of OpenJNLP)

Q: Is Web Start a general installer?

Web Start is different from classic, big blue gradient, pre-Internet, install-and-forget-it, single-shot installers. Web Start is designed for Java apps and, therefore, isn't of any help if you want to install Windows .exe apps that require a bunch of registry settings, for example.

Although Web Start doesn't offer offline installation (aka CD installers) out-of-the box, it's not hard to add them. Venus Application Publisher offers more than five different offline installation options that allow follow-up online upgrades. You can find out more at http://www.vamphq.com.

Sun has also a general application installation API in the works that seems to drag on forever. Check out Java Specification Request (JSR) 38 - Application Installation API at http://www.jcp.org/jsr/detail/38.jsp third-party link. The stated goal is to develop Java APIs that will enable cross-platform installation and de-installation of Java apps as well as platform specific apps.

(Status: Expert Group Formed - Yes, Public Review Underway - No, Community Draft Published - No, Proposed Final Draf Published - No)

Q: What's New In Web Start?

v1.2 Beta - June 2002

Web Start Promoted. Note that starting with Java 1.4.1 (aka Hopper) you can no longer download Web Start without a Java runtime (or a Java runtime without Web Start).

v1.0.1_02 - February 2002

v1.0.1_01 -

v1.0.1 -

v1 - December 2000

Q: Can I distribute Web Start apps without putting them on a web server (aka CD installers)?

Yes, you can. One option is to use the file:// protocol instead of http://.

Vamp (aka Venus Application Publisher) offers a couple of choices such as installing your app directly into Web Start's cache or using single, self-contained jars that include a built-in, ultra light-weight web server that serves up your app's jars from the installer's jar itself.

Client archives (.car) are standard jars that include all required jars, icons as well as a all required JNLP descriptors including extensions that are needed by an app in a single jar similar to RPM packages.

Q: Can I run Web Start Apps on a headless (monitor-less) UNIX system?

Headless (monitor-less) UNIX machines usually have no XWindow installed and, therefore, lack a browser. You can start your Web Start apps from the command line.

Web Start currently cannot run on headless UNIX systems even if you suppress Web Start's splash popup using the undocumented javaws.cfg.showSplashScreen false property.

What you can do, however, is to run your GUI-less apps with Web Start clones such as OpenJNLP or NetX that support command-line only launching without any download progress or signature GUI popups.

Q: Has Web Start won any Awards?

Q: Is Java Dead On The Desktop?

Java is alive and kicking. To see yourself check out these links:

Sun's bi-monthly Swing Sightings Series third-party link shows off many, many Java desktop apps from the Apollo Human Genome Browser to Tejina, a Japanese Handwriting Trainer using the Kunststoff Look And Feel.

JavaOne 2002 talk How to Build an Awesome Java Client with Swing third-party link (74 slides) by Scott Violet, Norbert Lindenberg and Dale McDuffie (Sun)

IBM's Eclipse Standard Widget Toolkit (SWT), a high-performance, low-footprint, cross-platform, open-source alternative to Swing online at http://www.eclipse.org third-party link

LimeWire, a Gnutella Peer File Sharing App, was Java's first killer app for non-developers tallying up more than ten million downloads from Joe Blocks in 2001 (average weekly download of two hundred thousand and three hundred thousand estimated daily users). Online at http://www.limewire.com third-party link

Q: What's the catch?

Biggie. Most desktop computer lack a factory pre-installed Java runtime plus Web Start add-on when bought in store. Broadband users need to download the ten mega Java runtime package themeselfs. Dial-up users need to get it on CD/DVD as a one hour download over a 28.8k modem is impratical.

Good News. Mac OS X ships with a factory pre-installed Java runtime plus Web Start. Java 1.4.1 (code-named Hopper) will include AutoInstall, a plug-in for Internet Explorer for Windows that installs Web Start and/or your app on the user's machine over the Internet through a single-click. Java's Plug-In installation automatically adds Web Start as a free bonus. Finally, a ten meg download isn't huge nowadays. It's roughly the size of the Adobe Acrobat Reader plug-in and much smaller than a MPEG movie.

Nuiscance

Q: What alternatives exist to Web Start and Java for rich cross-platform, zero-admin desktop apps?

HTML/Javascript (aka Dynamic HTML - DHTML)

pro:

con:

XUL/Python

see Mozilla (http://www.mozilla.org third-party link) or Luxor (http://luxor-xul.sourceforge.net third-party link) for details

XHTML/SVG/XForms

see W3C (http://www.w3c.org third-party link) for details

.Net Gtk#

see Mono (http://www.go-mono.com third-party link) for details

Other Open-Source Alternatives: XWT, Sash, etc.

Other Closed-Source Alternatives: Flash, Curl, etc.

Q: Who is using Web Start?

Check out the app directories listed in the link section categorizing hundreds of Web Start apps.

Q: How does Web Start differ from Applets?

Web Start != Applet 2.0/NT. Web Start is not a replacement for applets unless you abused applets for mega-sized pop-up windows floating outside of web pages. Applets run inside the web page on the browser's one and only Java runtime. In contrast Web Start apps run on its own Java runtime outside the browser.

Applets - dynamic content inside a web page in a browser

Web Start Apps - full-blown, stand-alone desktop apps that run without a browser

Q: Can I create my own Java runtime installers without breaching Sun's license?

Yes, you can. Read on for the fineprint.

Legalese demystified: Sun's Java runtime redistribution terms in plain-English:

Disclaimer: I'm not a lawyer, a ballerina, Scott McNeally or Elvis Presley.

You can freely (free-of-charge) redistribute Sun's Java runtime (including Web Start) with your masterpiece (known as value-added app).

Sun also allows you to repackage the Java runtime (so that you can auto-install it with your very own Web Start installer).

Taboos. Sun doesn't allow you to redistribute stand-alone Java runtimes (that is, without your app) on CDs in books or magazines, for example, without asking their licensing department first.

Also Sun doesn't allow you to redistribute pre-release (aka Beta) Java runtimes (e.g. JRE v.1.4.1 Beta) without permission.

Sun's license states that you aren't allowed to "modify" the Java runtime meaning you aren't allowed to change the code (e.g. replacing Sun's java.net.Socket class with your very own). Note that, "modify" in legalese doesn't forbid repacking. You can even drop some files from Sun's Java runtime distro if Sun tagged them as optional (vs. required).

Q: Can Web Start resume downloads?

Web Start doesn't support "resume download" on individual jars. However, Web Start will resume downloading the next jar that was not completed. Thus, the best work around for mega downloads over dial-up connections, for example, is to break up your app into several smaller jars instead of using a few biggies.

Q: Can I update running apps?

Q: Can Web Start do background updates and notify the user to restart her app to get the newest version?

A: You cannot check for updates in running app using the Web Start API. Web Start only checks for updates on startup.

Web Start 1.2 Update. Starting with Web Start 1.2 and greater, if the update check times out (that is, after 1+1/2 secs by default) Web Start will startup the cached version and continue the update check and possible download in the background. However, if there's a new version, Web Start won't notify the user.

Web Server Setup

Q: How can I add JNLP MIME-types to my ISP's Apache Web Server?

If you've read Web Start's docu you know that your web server has to return a special MIME type for JNLP files: application/x-java-jnlp-file.

It's not always easy to convince your web space provider to change their web server configuration. If your provider runs Apache (as many do) and hasn't switched off support for the .htaccess feature (which is usually true) there's an easier way: Just add these two lines to the .htaccess file at the top directory of your site (or create one, if it doesn't exit):

AddType application/x-java-jnlp-file    .jnlp
AddType application/x-java-archive-diff .jardiff

Now try to load a JNLP file from your site. If you browser still displays the content of the JNLP file instead of starting Web Start, shift-click the Reload button to make sure no caches are involved (this is at least how it works for Netscape).


As an alternative you can check if your web server supports scripts such as PHP or Perl and use it to set the MIME type header dynamically. In PHP this is a one line affair as the example below sent in by Marc Prud'hommeaux shows:


<? header ("Content-Type: application/x-java-jnlp-file"); ?>
<jnlp codebase="http://www.L2FProd.com/software/skinlf/jnlp" 
      href="demo.php">
  <information>
    <title>Skin LF Java Web Start Demo</title>
    <vendor>L2FProd.com</vendor>
    <homepage href="http://www.L2FProd.com/software/skinlf/" />
    <description>Skin LF Java Web Start Demo</description>
    <offline-allowed />
  </information>
  <resources> 
    <j2se version="1.4+ 1.3+"/> 
    <jar href="demo.jar"/>
    <extension name="Skin Look And Feel" href="skinlf.php"/>
  </resources> 
  <application-desc main-class="javawebstart">
  </application-desc>
</jnlp>

In the unlikely case, your provider supports Java Server Pages (JSP), but hasn't JNLP mime type support turned on; you can use the one line JSP page directive below:


<%@ page contentType="application/x-java-jnlp-file" %>

<?xml version="1.0" encoding="utf-8"?>
<jnlp codebase="http://localhost" href="hello.jsp">
  <information>
    <title>Hello Web Start</title>
    <vendor>Nobody</vendor>
    <desc>Hello Web Start Example</desc>
  </information>
  <resources>
    <j2se version="1.4+ 1.3+"/>
    <jar href="lib/hello.jar"/>
  </resources>
  <application-desc main-class="HelloWebStart"/>
</jnlp>
Installation and Troubleshooting

Q: How can I pre-install an app into the Web Start cache?

A brute force method is installing your app to your local machine and then taking the image and copying it onto different machines.

A better method is using Venus Application Publisher's Web Start Cache Utility code-named Celia. Celia allows you to install packages to your Web Start app cache without downloading them from the original web site. You can package apps you wish to install in jars and feed them to Celia. Celia will honor whatever codebase you specify in the JNLP descriptor and install all necessary files as if they were downloaded by Web Start itself from the original web site. You can find out more at http://www.vamphq.com/cache.html

Q: How can I change the Web Start application folder/cache?

Web Start doesn't allow you to change the application folder/cache.

However, Mik Tuver discovered the undocumented property below that lets you change Web Start's app cache. Example:

javaws.cfg.cache.dir=c:/Programme/JavaSoft/JWSCache

Q: Can I install Web Start silently?

Yes, use the /silent command-line flag (Windows only).

Q: Web Start returns a Bad MIME Type error. What's wrong?

This is a very common problem and most likely caused by Web Start's failed attempt to automatically detect your proxy settings. The "Bad MIME Type" error displayed by Web Start is somewhat confusing as it should really be a "Resource Not Found" error.

Your proxy will send back an error page either in HTML or plain text instead of the requested JNLP descriptor if it fails to get the JNLP descriptor requested by Web Start.

You can change your proxy settings for Web Start manually by starting the Application Manager and using the Preference panel. (Select File|Preferences to get there.)

Proxy Settings

You can use telnet to check what is holding back Web Start. Connect to the web server hosting the JNLP descriptor that causes the "Bad MIME Type" error. Once you are connected type in a HTTP GET request to check what the web server serves up. Example:

GET /venus.jnlp HTTP/1.0

You should get a response similar to the following:

HTTP/1.0 200 OK
Date: Wed Jul 18 19:57:33 CDT 2001
Server: Venus Light-Weight HTTP Server
Content-length: 1183
Content-type: application/x-java-jnlp-file

<jnlp [...]>

Now that you know that the web server returns the correct MIME type, all you need to do, is figure out your proxy settings.


Note, starting with version 1.2 Web Start accepts JNLP startup files even if they ship with the wrong MIME type badge (e.g text/plain instead of the proper application/x-java-jnlp-file). However, if you use jardiffs (that is, jar patches that hold only the changes to fix up outdated jars and turning them into shiny new jars sporting the latest and greatest bells and whistles) Web Start requires the proper MIME type to differentiate between plain-vanilla jars (application/x-java-archive) and jars holding jardiffs (application/x-java-archive-diff).

Q: Does Web Start support Mozilla?

Yes, it does. Mozilla works out of the box on Windows. Unfortunately, you have to register Web Start manually as a helper app to Mozilla on non-Windows boxes. Here are the steps:

Note, that Sun's JavaScript Web Start detection script doesn't work for Mozilla. Adding Sun's JavaScript Web Start detection script to your HTML page is extremley short sighted and bad practice anyway and should be avoided. If you want to launch Sun's Web Start demo apps, use the no JavaScript page version instead of the malicous JavaScript page.

Q: Why can't Web Start and Microsoft Proxy Server get along?

Here are some postings showing Microsoft at its best:


If your Web Start client is behind a Microsoft Proxy Server and user authentification is switched on, your Web Start Java app never starts. It will work with anonymous authentification, however.

At some customer site the starting app stops when it tries to transmit serialized objects. On other sites we get an 407 "Proxy Authenfication required".

In the Web Start docs we can read "... Web Start will also prompt you for a user name and password required to access an authenticating proxy server. " Did anybody ever see this dialog with Web Start and Microsoft Proxy Server?


Microsoft Proxy Server uses NTLM authentication to authenticate its clients. Unfortunately, NTLM authentication is based on a Microsoft proprietary protocol and there is no official specification. Although NTLM authentication is similar to the standardized and widely-used BASIC authentication, it is not exactly the same and clients expecting a BASIC authentication handshake will fail unless they have a special WinSock Proxy Client installed (another Microsoft component, of course).

My guess is that Web Start is only able to handle BASIC authentication (which would definitely make sense). In any case, it cannot implement a handshake for NTLM because there is no official specification.

Web Start works fine with a proxy using BASIC for authentication.

For more information on NTLM see


If anyone else than me is interested in trying to write some code which will accomplish this, please drop me an email at andda715@student.liu.se. Then we could set up a project at sourceforge.net and see what happens.

- Anders Dahlberg

Btw, I've found some c code which does this (a mod to apache), I'm sure we can copy this code if we ask nicely :).


Dmitry Rozmanov has created a free, open-source NTLM authorization proxy server in Python that supports Microsoft's proprietary NTML protocol. Features include:

See http://www.geocities.com/rozmanov/ntlm/ third-party link for details.


The NTLM authorization issue is also logged at Sun's Bug Parade at http://developer.java.sun.com/developer/bugParade/bugs/4423881.html third-party link.

Sun's policy is not to support Microsoft's proprietary NTLM authentication. Instead Sun's suggests that you upgrade to Microsoft Internet Accelerator Server (IAS) as it supports HTTP digest authentication and use it instead of the preconfigured, Microsoft-only NTLM.

HTTP digest authentication like NTLM authentication no longer sends plain-text passwords over the wire as HTTP basic does. You need to upgrade from Microsoft Proxy Server to the rebranded Internet Accelerator Server as HTTP digest authorization is not supported in the older Microsoft Proxy Server.


Luigi Dragone wrote a 100% pure Java implementation of the Micropoly NTLM authentication protocol (released under the GNU GPL). Jump to http://www.luigidragone.com/networking/ntlm.html third-party link for details.


Java 1.4.2 Update. NTLM authentication support is forthcoming in Java 1.4.2 (Mantis).

Q: Can I install Web Start on Windows without admin privileges?

Not out-of-the box using Sun's Web Start installer. Here are some roadblock you have to overcome:

Here are some voices from the trenches:


We had no luck allowing the users to install, unless they were give admin priv, which we did temporarily. That worked fine.

We also thought we would pre-install it on the boxes but it seems that it will only work under the same user id that did the install. So we can't have an admin account load it up for everyone. Each user has to do it when they get their box, and has to have admin help when they do it. Kind of the worst situation since it requires the user and the admin to do it.


  1. Because of the registry settings the user needs at least "main user" properties for the installation to be successfull (i.e. setting the MIME type, etc.). Unfortunately, the Web Start app manager icon is put into the installing user's desktop folder, so that only this user will have the icon on his desktop and hence be able to start web start without problems. Our admins copy the icon to the All Users desktop so that everybody "has" it. Alternatively, you can give the user instructions how to acess web start or create a Web Start desktop icon. Having the installer put the shortcut to the All User's desktop folder may solve this problem.
  2. In our configuration the program folder (C:\Program Files) is read-only for normal users, so that they cannot install software. Because the cache of Web Start is located below the install directory, which is the program folder by default, normal users cannot let Web Start write to the cache, and therefore cannot download applications.

We solved this problem by installing Web Start not to the program folder. This cannot be done automatically with the silent option, because there is not command line parameter through which you can specify the installation directory. So we do it manually for each Web Start installation (or use a standard hard disk image for standard configurations, where Web Start is included).

This problem could be solved, by moving the Web Start cache to the user's area or by giving us the possibility to specify an install directory from a command line using the silent install. Nullsoft has apparently this option (-D), but somehow, I am not successfull to carry it out. I asked already that the Nullsoft Installer script is being published so that everybody could modify it to his need. No answer yet to this topic.

- Thomas Gulden


What is possible under Windows, is allowing access to certain registry keys for all users: http://www.microsoft.com/office /ork/xp/one/deph02.htm third-party link


As a workaround, you can throw out Windows and replace it with Linux. Under Linux it is possible to do all necessary steps as common user. The cache will be put in the user's home directory, the "mime-type->file extension" association is set up in the user's .mimetypes file and the "mime-type->application" association in the user's .mailcap file.


Thomas Gulden reports on trouble with shortcuts on multi-user Windows machines using a single Web Start install:

If more than one user works on a machine, the shortcut creation for the second user (lets call her Betty) (not the lucky girl who installed Web Start) faces some bad karma.

1) When Betty logs in she does not see any icon for a downloaded Web Start app. This is correct, because Web Start creates the shortcut in the user's home directory leaving Betty to create the icon herself. When she uses the menu, she only finds a menu item allowing her to delete the shortcut (even though there isn't any). This is because Web Start maintains only a global property to track if it has created icons or not. This seems to be inconsistent design as Web Start should store the property in the user's home directory for each user instead of once for all.

2) After deleting the shortcut Betty can now invoke "create shortcut" again. If she dares to do so, a shortcut shows up on the desktop sporting Web Start's default icon instead of the app's very own. We found out that this is caused by the user privileges assigned to the icon in Web Start's cache. Only the user who first installed the app has the right to access it and this restriction seems only to apply for the app's icon, the rights for all other files are set to everyone.


Web Start 1.2 Update. Web Start now stores its cache under the user's folder (and no longer in the read-only program folder).

Q: Why doesn't Sun's Javascript Web Start detection script work for my household browser?

Sun's Javascript Web Start detection script works only with Netscape 4.x and Internet Explorer. If you use Netscape 6.x, Mozilla, Opera or other browsers, Sun's Web Start detection script fails because Netscape 6.x, Opera and Mozilla, for example, implement navigator.mimeTypes different than Netscape 4.x.

In conclusion, don't include Sun's Javascript Web Start detection script into your HTML page unless you work for Microsoft, instead point directly to the jnlp file. Using Sun's Javascript Web Start detection script not only blocks all browsers other than Internet Explorer but also hinders HTML parsers to retrieve the embedded jnlp links, in case you want to use the HTML page as Web Start's default app page, for example.

Q: How can I change the proxy configuration in javaws.cfg?

If you want to set the proxy setting to none, use

javaws.cfg.proxy.setting=NONE

Note, that under Windows there are two javaws.cfg files. javaws.cfg can be in "\Program Files\Java Web Start\javaws.cfg" which will get used for all users on that machine or it can be in the user's profile directory in ".javaws\javaws.cfg". Web Start's App Manager will put your settings in the user's profile, but you can actually put it in either.

Q: Why doesn't my app run under Web Start?

Note, that Web Start only ships jars to the user's desktop. You need to retrieve all your resources either from jars or over the network using HTTP.

To find out what holds back your app, you might follow these steps:

Check if you packed up everything your app needs into jars by trying to run it from the commandline without any classpath settings using the -jar switch. Example:

java -jar myapp.jar

Try to fire up your app with Web Start using a file:/// codebase in your jnlp file. Using file:/// spares you from uploading your jars and setting up your own web server. Example:

<jnlp href="myapp.jnlp" codebase ="file:///c:/sandbox/myapp/startup" >

Now you are almost there. If Web Start cries "Resource Not Found" when trying to download your jnlp file or jars check if your web server's jnlp MIME types are set up correctly. You can check up on your web server by using telnet and sending a GET request to your web server. See "Web Start returns a Bad MIME Type error. What's wrong?" for details.

If your web server's mime types are setup correctly and Web Start still refuses to start up your app , you need to figure out your proxy settings.

Q: Why can't I start Web Start's app manager under Windows? Why does the app manager's preferences dialog fail to appear?

This might be a proxy issue. Try to turn off your proxy by putting

javaws.cfg.proxy.setting=NONE

in your javaws.cfg file and see if it Web Start's app manager shows up.

Web Start checks your Windows registry to find out your browser's proxy settings.

You can extract com.sun.javaws.proxy.WinInternetProxy from javaws.jar and run Cygwin strings on it to find out what keys Web Start is looking for. If you're on a different platform, try a similar hack with whatever com.sun.javaws.proxy class shows up in your stack trace.

Here are the registry keys for Internet Explorer:

HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Internet Settings

If you upgraded to Internet Explorer 5, Internet Explorer 4 might have left bind bad values in AutoConfigURL. Delete AutoConfigURL and see if it makes a difference.

Q: Why doesn't Web Start reprompt for proxy logins?

Q: When I start my app and enter a wrong password in the proxy login dialog poped up by Web Start my app starts. However, whenever I use HttpUrlConnection and read the response an exception gets thrown saying "too many server directs".

Why doesn't Web Start pop up the dialog again if the password to the proxy was wrong? How can I tell Web Start to popup up the dialog again without rebooting the app?

A: I downloaded the Web Start source code. Web Start's proxy login dialog (aka JAuthenticator) gives you one shot to type in your right password. If you get it wrong, Web Start won't reprompt for another try.

Q: Can Web Start handle multiple XML parsers at once?

Web Start uses JAXP for parsing XML. I want to use Xerces 1.1.3. However, xerces.jar includes newer DOM classes that conflict with the older DOM classes shipped with Web Start. I also use SOAP which depends on newer DOM classes as well. When my app makes a SOAP call that uses a method available only in the newer DOM classes, Java's runtime throws a NoSuchMethodError because it is using the older DOM classes from jaxp.jar rather than the newer ones from xerces.jar.

Shouldn't Web Start use a separate ClassLoader to isolate my app's jars from Web Start's own to avoid class loading conflicts?


I face a similar problem. The following line throws ClassNotFoundException:

org.xml.sax.helpers.ParserFactory.makeParser("com.ibm.xml.parsers.SAXParser");

I can work around the multiple xml parser conflict by placing the XML jars (xerces.jar and xml4j.jar) in the runtime's lib/ext directory. This works for internal testing, but is not much use otherwise.


I've hit the same dead end using Web Start 1.0.1 under Mac OS X 10.1.

Web Start's jar (javaws.jar) contains what seems to be a dumbed-down version of the minimum XML parsing needed to interpret jnlp files.

Unfortunately, it's inadequate for my needs that require Xerces 1.4.3. Web Start's built-in XML package lacks (among many others) Document.importNode(), alas. NoSuchMethod errors abound. Sigh.

I'm going to experiment with custom class loaders to see if I can find a workaround.


If you want to use a specific XML parser bundled with your app, instead of whatever XML parser happens to get picked up by JAXP, you can set the property javax.xml.parsers.DocumentBuilderFactory in your JNLP startup file. Example:

<resources>
  <j2se version="1.3"/>
  <jar href="xerces-1.4.3.jar"/>
  <property name="javax.xml.parsers.DocumentBuilderFactory" 
            value="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
</resources>

Q: How do I know that jardiff is working?

To make jardiff work you need to add version attributes to your <jar> tags in your jnlp startup file. Example:

<jar href="/jars/AccentVic.jar"  version="1.1"/>

On the server you need to use Sun's JnlpDownloadServlet to let it handle Web Start requests for your jars as a plain Web Server won't suffice. You can get JnlpDownloadServlet for free by downloading Sun's JNLP developer's pack third-party link.

You also need to tell Sun's JnlpDownloadServlet what version a jar belongs to. You can use either a name mangling convention that adds the version directly to your jar's filename (e.g. AccentVic__V1.1.jar) or add versions entries to version.xml in the directory holding your jars.

To check if everything works turn on JnlpDownloadServlet's debug log. Add two init parameters to JnlpDownloadServelt's config file. Example:

logLevel=DEBUG
logPath=<log file name>

After a Web Start request you should find something like below in your servlet log file:

JnlpDownloadServlet(3): Resource returned: /jars/AccentVic1.jar
JnlpDownloadServlet(3): Generating JarDiff for Accent70Vic.jar 1.0->1.1
JnlpDownloadServlet(4): Generating Jardiff between 
    /usr/WebSphere/AppServer/hosts/Accent/WebApp/jars/Accent70Vic.jar and 
    /usr/WebSphere/AppServer/hosts/Accent/WebApp/jars/AccentVic1.jar Store in 
    /tmp/jnlp29099.jardiff
JnlpDownloadServlet(4): JarDiff generation succeeded
JnlpDownloadServlet(3): JarDiff returned for request

This tells you that JnlpDownloadServlet just dished out a jardiff and everything works as advertised.

Q: How can I install Web Start on Unix as root once for all users?

Brett Humphreys solved the puzzle. Web Start updates the current users' .mime.types and .mailcap files. However, if you install Web Start as root (that is, once for all users), it won't update netscape's global files, so you have to do it yourself.

Here are Brett Humphreys's distilled instructions to register Web Start as Netscape's helper app for JNLP mime types as root once for all users.

Follow Web Start's install instructions, including

  1. Downloading the zip file for Solaris
  2. Unzipping the zip file to a logical global install directory (e.g. /usr/local)
  3. run the install.sh script to install

One of the last messages the install script spits out is:

Updating ~/.mailcap...
Updating ~/.mime.types...

This updates the MIME types and mailcap files for the current user only; use the instructions below to update them for all users.

These instructions assume /opt/NSCPcom as Netscape's install directory. To find out where Netscape hides on your machine, type:

which netscape

This should reveal a directory path telling you where Netscape's executable hangs out, for example:

/opt/NSCPcom/netscape

As root, open the file /opt/NSCPcom/etc/mailcap (/usr/local/lib/netscape/mailcap on Linux) and append the line below to register Web Start as Netscape's helper app for JNLP's mime type:

application/x-java-jnlp-file; /export/home/bretth/javaws/javaws

/export/home/bretth/javaws/javaws tells Netscape where the Web Start executable hangs out. If Web Start frequents a different directory on your machine, change it accordingly. Save your changes and close the file.

As root, open the file /opt/NSCPcom/etc/mime.types (/usr/local/lib/netscape/mime.types on Linux) and append the line below:

type=application/x-java-jnlp-file desc="Java Web Start"
exts="jnlp"

Close any running Netscape browser windows and restart it to kick start Web Start apps.

Q: Why does Web Start use two javaws.cfg files?

Web Start uses two javaws.cfg files.

The first one resides in Web Start's installation directory and holds the initial settings (mainly the location of Java runtimes available at installation time.)

The second one resides in the users "home" directory (whatever the system property user.home returns varies from Linux to Windows). This config file holds the user's configuration changes such as proxy settings, new or changed Java runtimes, logging, console, and other preferences.

Q: Why Can't Web Start Create Desktop Shortcuts?

Web Start uses the app's title stored in the jnlp startup file (e.g. <title>Venus Application Publisher<title>) to create the desktop shortcut. Make sure your app's title doesn't contain illegal characters (such as \ / : * ? " < > | ), otherwise you end up with the Web Start popup: "unable to create shortcut, try again later". Also check your title's length as too long titles cause problems as well (under Windope you can use up to 255 characters).

Q: How can I autoinstall Web Start?

Franklin Schmidt has done it using Internet Explorer and the Java Plug-In. See yourself at http://www.myquerytool.com/download/ third-party link.

Franklin Schmidt uses JavaScript to check if Web Start is installed. If it isn't, he links to a "automated Web Start install" page looking like this:

<html>
  <body>
  <h1>Installing Java</h1>
  <OBJECT
     CLASSID="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
     width="0" height="0"
     codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_0-win.cab#Version=1,4,0,0">
    <PARAM NAME="code" VALUE="Redirect.class">
    <PARAM NAME="type" VALUE="application/x-java-applet">
    <PARAM NAME="where_to_next" VALUE="/download/?a=b">
    You did not install Java.
    <p>Please use the <b>Back</b> button to return to the previous page.
  </OBJECT>
  </body>
</html>

This magic HTML snippet installs the Java Plug-In plus Web Start. Once installed it runs the "Redirect" applet below taking the user back to the download page.

public class Redirect extends Applet 
{
  public void start() 
  {
    try 
    {
      getAppletContext().showDocument(
        new URL(getCodeBase(),getParameter("where_to_next")) );
    } 
    catch(MalformedURLException e) 
    {
      throw new RuntimeException(e);
    }
  }
}

Sun has added autoinstall to Web Start 1.2 for Windows upcoming in fall 2002 (betas expected this summer) with Java 1.4.1 (aka Hopper).

Q: What autodownloadable Java Runtimes does Sun offer?

Sun offers:

Source: http://java.sun.com/products/javawebstart/developers.html#auto third-party link

Sun has not yet posted Java bundles for 1.4 or even 1.3.1 on their site. To lobby Sun cast your vote at Sun's bug parade at http://developer.java.sun.com/developer/bugParade/bugs/4638667.html third-party link

Q: How can I change the splash screen?

Web Start uses two splash screens. A mini splash screen (miniSplash.jpg) that pops up before Web Start kicks off the Java runtime and gets torn down once the Java runtime takes over. A progress splash screen that tells you what Web Start is up to (downloading, checking for updates, checking signatures, etc.) and what app is about to popup on on your desktop.

You can turn off the mini splash screen using the javaws.cfg.showSplashScreen setting in the Web Start configuration (javaws.cfg). See "How can I turn off Web Start's splash screen?" for details.

Using brute force, you can sneak in your very own splash screen by overwritting Sun's miniSplash.jpg image.

Starting with Web Start 1.2 and greater you can now choose your own mini splash screen image in your app's XML startup file using the <icon> tag. Example:

<icon kind="splash" href="venus.gif" />

Note, however, that Web Start will frame your image on the first start up. For all following startups Web Start will popup the freshly minted splash screen showing off your very own image.

Also note that the Web Start Jukebox (that is, Application Manager) uses its own splash screen (splash.jpg).

Q: How can I turn off Web Start's splash screen?

The Splash Screen Firewall Dead-Lock. If your firewall forbids opening connections on random ports, Web Start likely gets stuck in an endless loop trying to get through to the splash screen server.

To keep you entertained while the Java runtime starts offs Web Start kicks off a tiny, turbo-charged, non-Java, native app (splash.exe) that pops up a splash screen in an instant. Once the Java runtime is up and running Web Start tells the splash screen to shutdown. The magic works because the tiny splash screen app is a full-blown TCP server listening on a random port waiting for the shutdown signal.

To avoid this dead-lock scenario, turn off the splash screen by adding javaws.cfg.showSplashScreen=false to your Web Start configuration (javaws.cfg).

If Web Start still hangs, dive into the Windows registry and change the .jnlp file type setting by adding the extra -Xnosplash switch for launching (for example "C:\Program Files\Java Web Start\javaws.exe" "-Xnosplash" "%1").


Web Start 1.2 Update. jdunnick reports: In a fresh Web Start 1.2 install, there appears to be no more splash.exe and the javaws.cfg.showSplashScreen and -Xnosplash properties no longer work. I guess it all changed when Sun added custom splash screens.

Q: How can I create a shortcut on the first launch?

By default Web Start pops the desktop-shortcut-icon-creation question on the second launch.

If you want Web Start to pop the question on the first launch, use the Web Start Wurlitzer (that is, the Application Manager) to adjust the setting. Note, you can also choose "always create shortcuts" or "never install shortcuts".

You can also adjust the desktop-shortcut-icon-creation setting directly in the Web Start configuration (javaws.cfg) instead of klicking around in the wurlitzer. Use the javaws.whenInstall property and set the value to your liking: 0 - Always; 1 - Ask on first startup; 2 - Ask on second startup; 3 - Never. Example:

javaws.whenInstall=1

Q: How can I auto-download an international Java runtime?

Web Start passes your computer's locale (that is, language and country code, for example en_US or de_AT) to Sun's auto-download servlet. For en_US locales Sun's servlet dishes out the US English version, for all other locales Sun's servlet dishes out the international version.

Note, that you can only download an international version if you set the locale on your machine to something other than US English (en_US). No magic product version string in the JNLP startup file exists to get you an international version for a US English locale or a US version for a non-US locale from the Sun site.

Note, also that Web Start will not even contact Sun's auto-download servlet if your app requires an international version when your computer already has an US version installed.

As a workaround you can roll your own Java runtime installer that dishes out a international version no matter what locale Web Start sends over. Use a Java runtime product version to request an international version. Example:

<j2se version="1.4+" href="http://cloud7.org/autodl/j2se-int" />

Q: What's the best way to move my Web Start apps to a different server?

If you move your Web Start app to a different server (that is, different codebase in Web Start parlance), your users will likely end up ruminating why they now have two identical icons for your wonderful app on their desktop and how they differ.

To help your user differentiate your apps hosted on the old server (e.g. cloud7.com) from your apps hosted on the new server (e.g cloud8.com), use a different title and description in your JNLP startup file (for example, use "Whack-A-Bill @ Cloud Seven " and "Whack-A-Bill @ Cloud Eight" instead of just "Whack-A-Bill" for both.)

Tell your users to fire off the Web Start Jukebox (that is, application manager in Web Start parlance) and delete your old tune from the playlist (that is, downloaded apps or favorite apps).

Note, if you delete your app from the playlist, Web Start won't clean up its cache and throw out the junk (that is, the now orphanded jars, icons, and so on), instead Web Start leaves the cache surgery up to you. Open up the hood (that is, the Web Start cache directory e.g. c:/java/jws/v101/.javaws/cache) and delete the branch in the directory tree that holds your old app parts (e.g.http/Dwww.cloud7.com/P80/DMapps translating to http://www.cloud7.com:80/apps).

HTTP Redirects. Note, you can also use HTTP redirects such as 301 Moved Permanently or 307 Moved Temporarily.

Q: How can I install Web Start with a single click using the ActiveX auto-installer from an Intranet?

<OBJECT 
  CODEBASE="http://<yourhost>/plugin/j2re-1_4_0_02-windows-i586-i.exe#Version=1,4,0,2"
  CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
  <PARAM NAME="type" VALUE="application/x-java-applet">
  <PARAM NAME="app"  VALUE="http://<yourhost>/<yourapp>.jnlp">
  <PARAM NAME="back" VALUE="true">
    You did not install Java.
    Please use the Back button to return to the previous page.
</OBJECT>

For more info check out:

Q: How can I install a Java Runtime plus Web Start with a single click using the ActiveX auto-installer?

Web Start 1.2 Update. If you use the standard codebase (printed in the Dev Guide), that is,

CODEBASE="http://java.sun.com/products/javawebstart/autodl/jinstall_javaws-1_2-windows-i586.cab"

the Windows ActiveX auto-installer will only install Web Start (without a Java Runtime) and will configure it using already installed Java runtimes. If the auto-installer finds no Java runtime on your machine, you will end up with the error below:

  
Bad installation: Error invoking Java VM(SysExec) bin\javaw.exe.

To install Web Start plus a Java Runtime you need to use a different cabinet (.cab). Use

CODEBASE="http://java.sun.com/products/autodl/jinstall-1_4_1-windows-i586.cab"

to install the Java Runtime 1.4.1 plus Web Start, for example.


mswanson posted a complete HTML auto-download skeleton and comments "This installs the Java Runtime 1.4.1 AND Web Start 1.2 AND launches our Web Start app. Fantastic."

<HTML>
  <BODY>
    <OBJECT
      CODEBASE="http://java.sun.com/products/plugin/autodl/jinstall-1_4_1-windows-i586.cab#version=1,4,1"
      CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
      <PARAM NAME="app" VALUE="http://x.y.com/sw/ScheduleWorld.jnlp">
      <PARAM NAME="back" VALUE="true">
      <!-- Alternate HTML 4 browsers that can't instantiate the object -->
      <A HREF="http://java.sun.com/cgi-bin/javawebstart-platform.sh?">Download Java Web Start</A>
    </OBJECT>
  </BODY>
</HTML>

Q: How does Web Start check for updates? What's up with forceUpdate?

rustycng wonders: Does anyone know how Web Start checks for updates? I'm wondering if breaking a few big jars in more smaller jars speeds up or slows down version checking?

The oracle speaks: (Using basic protocol) Web Start sends out an HTTP HEAD request for every jar in your app's XML startup file to check the timestamps of the latest and greatest jars stored on the server against the jars stored in your Web Start cache. Thus, breaking your app into more jars results in more HTTP HEAD requests and may slow down the initial update check.

Note, that if you include the <offline-allowed> tag, Web Start will turbo charge your app from the cache while running the timestamp checks in the background (even if you're online).


The oracle speaks again: When launching an app (even with <allow-offline> in the XML startup file), Web Start kicks off a thread to check the timestamps (or version id's if using the version protocol). If Web Start can find the answer quickly (that is, within 1+1/2 seconds by default), or if the XML startup file doesn't include <allow-offline> (thus, requiring online use), the check will complete and Web Start downloads all updated jars before launching the app.

However, if the XML startup file includes <allow-offline> and the update check times out, Web Start will launch the app from the cache while the thread continues to check for updates in the background.

If the background update check thread finds fresh jars, it will set default.forceUpdate to true (in the app's property file stored in the Web Start cache (e.g. ALvenus.jnlp)) to force Web Start to update the app the next time you run it again.

Resource Loading

Q: How can I load resources from a jar?

Check out my resource loading tutorial. You can find it at http://www.vamphq.com/tutorial.html.

Q: How can I load resources specified in a property file?

Use the class:// URL protocol as you can't use absolute or relative file paths. For a detailed explanation check out Rachel, an open-source Resource Loading Toolkit for JNLP/Web Start. It ships with user docs and examples. Note, that your apps will also work without Web Start. You can find Rachel at http://rachel.sourceforge.net third-party link

Q: Can I change my apps look and feel?

Yes, you can. However, there are some limitations and workarounds you should be aware of. Check out the following bug reports:

Here is the code fragment for switching to the Kunstoff look and feel:

try
{
  com.incors.plaf.kunststoff.KunststoffLookAndFeel kunststoffLF
    = new  com.incors.plaf.kunststoff.KunststoffLookAndFeel();
  kunststoffLF.setCurrentTheme( new com.incors.plaf.kunststoff.KunststoffTheme() );
  UIManager.setLookAndFeel( kunststoffLF );
}
catch ( javax.swing.UnsupportedLookAndFeelException x )
{
   // handle exception
}

// make Web Start happy
// see http://developer.java.sun.com/developer/bugParade/bugs/4155617.html
UIManager.getLookAndFeelDefaults().put( "ClassLoader", getClass().getClassLoader()  );

I am not sure, if this is a workaround to something that should work by itself.

Q: How can I load Skin Look and Feel themes from a jar?

Use the class:// URL protocol. Example:

URL themepack = new URL( "class://ThemeAnchor/skinlf/themes/modern.zip" );
Skin skin = SkinLookAndFeel.loadThemePack( themepack );

For a detailed explanation check out Rachel, an open-source Resource Loading Toolkit for JNLP/Web Start. It ships with user docs and examples. You can find Rachel at http://rachel.sourceforge.net third-party link. In case you don't know SkinLF, you can find out more at http://www.l2fprod.com third-party link.

Q: How can I reference a Java Help helpset?

Note, that you cannot use absolute or relative file paths. Instead pack your helpset in a jar and use the resource anchor trick to reference it. See the Resource Loading Tutorial for details. Here is a code snippet that loads a helpset:

public class HelpSetResourceAnchor
{
   // do nothing; add it to the jar with all your helpsets
}

public class HelloHelp extends JFrame
{
  JHelp   _browser;
  HelpSet _helpset;

  public HelloHelp( String topic_id )
  {
   try
   {
     // use resource anchor trick to reference helpset
     ClassLoader cl = HelpSetResourceAnchor.class.getClassLoader();
     URL url = cl.getResource( "hello.hs" );
     _helpset = new HelpSet( cl, url );

     _browser = new JHelp( _helpset );
     _browser.setNavigatorDisplayed(true);

     getContentPane().setLayout(new GridLayout());
     getContentPane().add( _browser);

     setSize(500, 600);
     setLocation(0, 0);
     setTitle( "Hello Help");

     showHelp( topic_id );

     setVisible(true);
  }
  catch (Exception ex)
  {
     System.out.println("*** error: " + ex.toString() );
  }
}

public void showHelp( String topic_id )
{
  try
  {

   if( topic_id.equals( "" ) )
      topic_id = _helpset.getHomeID();

   _browser.setCurrentID( topic_id );
  }
  catch (Exception ex)
  {
     System.out.println("*** error: " + ex.toString() );
  }
}

Q: How can I list all resources in a jar?

Java doesn't currently support a method to list all resources in a jar. You can only retrieve one resource at a time.

What you can do, however, is create your own index page and retrieve it from your jar so you know what treasures it holds. Here is an example how an index page looks like. Feel free to invent your own format:

template.1=template/brief.htt
startup.1=startup/icon.xul
startup.2=startup/key.xul
startup.3=startup/menu.xul
startup.4=startup/toolbar.xul
images.1=images/about.gif
images.2=images/blank.gif
images.3=images/book.gif
images.4=images/exit.gif
images.5=images/folder.gif
images.6=images/world.gif

Q: Can I use my own custom ClassLoader?

Yes, you can. Note, that Web Start uses its own class loader. If you want to delegate class loading from your class loader to Web Start's class loader use:

ClassLoader wcl = Tool.class.getClassLoader();
URLClassLoader cl = new URLClassLoader(urls, wcl);

Where Tool.class is a class loaded by Web Start's own class loader (e.g. your entry point class holding main() packed up in a jar listed in your JNLP startup file).

Don't use ClassLoader.getSystemClassLoader() as a delegate, e.g.

ClassLoader scl = ClassLoader.getSystemClassLoader();
URLClassLoader cl = new URLCLassLoader(urls, scl);

unless you want to exclude all jars listed in your JNLP startup files from the search path. Note, that if you don't pass in a parent class loader (aka delegate) to your own custom class loader Java will automatically pick the system class loader as your custom class loader's delegate.

As an alternative you can set your own URLClassLoader as the context class loader for the event dispatch thread (aka Swing GUI thread) at the beginning of your app. Example:

public static void main(String[] args)
{
  ...
  ClassLoader wcl = Tool.class.getClassLoader();
  URLClassLoader cl = new URLClassLoader(urls, wcl);
  try
  {
    EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
    eq.invokeAndWait(new Runnable() {
      public void run() {
        Thread.currentThread().setContextClassLoader(cl);
      }
   });
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
  ...
}

If you want that Web Start downloads, caches and updates your jars but doesn't load them, you can add your jars to a jar that's listed in your JNLP startup file. Example:

Contents of plugins.jar:
  bookmark.jar
  history.jar
  PlugInAnchor.class  // one class need for identification

You can use your own class loader (based on URLClassLoader) to load the classes packed up in the jar's jar according to your own policies.


Note, that if you load classes with your own ClassLoader, you should also install your own SecurityManager (or none) by calling System.setSecurityManager( null ), otherwise you might run into security access violations even if you signed all your jars. Web Start's built-in security manager only assigns all permissions to the classes loaded by its own JNLPClassLoader.


iceryx reports: The classes I loaded with my own URLClassLoader didn't have the same permissions as the classes loaded directly through Web Start. So I included my own policy file in a jar to grant java.security.AllPermissions to all codebases. Then in my main class, I wrote:

URL policyUrl = Thread.currentThread().getContextClassLoader().getResource("my.java.policy");
Policy.getPolicy().refresh();

This fixed it. I guess that when you give "all-permissions" to your Web Start app, it assigns java.security.AllPermissions only to code loaded from the Web Start codebase, but not to code from other codebases. Changing the policy widened this permission to everything.

As another alternative you can also write your own Policy subclass permitting everything and then call Policy.setPolicy() to turn it on.

Q: Why do I get a class loading error when turning off the Web Start debug console?

Java 1.4 Update. Q: In my Web Start app I create an XMLReader using:

XMLReader r = XMLReaderFactory.createXMLReader( "org.apache.xerces.parsers.SAXParser" );

Everything works under Java 1.3.1, but starting with Java 1.4.0 or 1.4.1 the class loading fails. If I turn on the Web Start debug console, everthing works again. But if I turn off the Web Start debug console, Web Start can't load the class org.apache.xerces.parsers.SAXParser anymore. What's going on?

A: Bug #4665132 (fixed in Java 1.4.2) may cause your trouble. In Java 1.4 and greater, if no window is shown for a while (frequently on startup when the console is not on) the Java runtime will dispose the AWT EventQueue plus the EventDispatchThread, and later create a new queue and event thread when a window gets a message. However, when the runtime creates a new EventDispatchThread it sets the wrong ContextClassLoader for Web Start, thus breaking your code.

If this bug bites you, you can add a windowOpened event handler to your main window to reset the correct ContextClassLoader as a workaround. Example:

windowOpened(WindowEvent e) 
{
  Thread.currentThread().setContextClassLoader(AppFrame.class.getClassLoader());
}

As an act of despairation you can also side-step the dynamic class loading bug by hard-coding your SAXParser. Example. Use

XMLReader r = new org.apache.xerces.parsers.SAXParser();

instead of

XMLReader r = XMLReaderFactory.createXMLReader( "org.apache.xerces.parsers.SAXParser" );

Q: I am developing a small Web Start distributed app using JBoss 3.0.2 as a backend. Everything works fine until I turn off the Web Start debug console and I end up with the exception below. If I turn on the debug console again, everything works fine again. What's going on?

javax.naming.NoInitialContextException: Cannot instantiate class: 
  org.jnp.interfaces.NamingContextFactory. 
Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory

A: loretian reports: The AWT event dispatch thread uses the wrong class loader. Before your event handler code does anything set the correct ContextClassLoader. Example:

  
Thread.currentThread().setContextClassLoader( yourClass.class.getClassLoader() );

That fixed it for us.

JNLP Descriptor (aka Start-Up File)

Q: Why can't Web Start find my main class?

Make sure your main class is the first jar listed in the resources section. As an alternative you can set the jar's main attribute. (See JNLP Tag Reference for details.) Example:

<jar href="lib/mailicep.jar" main="true" />

Q: How can I specify a relative codebase in the JNLP descriptor?

Use Sun's jnlp-servlet that is part of Sun's Web Start developer's pack. It allows you to set jnlp.codebase to $$codebase and jnlp.href to $$name. Sun's jnlp-servlet will replace $$codebase and $$name with the correct values at run-time. Sun's jnlp-servlet also supports different versions of the same file and jar diffs (aka incremental updates).

A more light-weight approach is to rewrite your JNLP as a JSP. This allows you to put the JNLP file on any JSP-enabled host you want. Note that both codebase and href in the example below are pulled from the request and are not hard-coded.

<%@ page
 contentType="application/x-java-jnlp-file"
 info="My JNLP"
%>

<%
 StringBuffer codebaseBuffer = new StringBuffer();
 codebaseBuffer.append(!request.isSecure() ? "http://" : "https://");
 codebaseBuffer.append(request.getServerName());
 if (request.getServerPort() != (!request.isSecure() ? 80 : 443))
 {
   codebaseBuffer.append(':');
   codebaseBuffer.append(request.getServerPort());
 }
 codebaseBuffer.append('/');
%>

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+"
      codebase="<%= codebaseBuffer.toString() %>"
      href="<%= request.getRequestURI() %>">
[...]

Note, that you can do the same in Perl, PHP or whatever CGI scripting language you prefer.

Q: How can I pass in arguments to my app using a HTML hyperlink?

One trick is to make sure not to include the href attribute in the JNLP file that your cgi-script sends back to Web Start. This will tell Web Start to disable the update check on JNLP files, and Web Start will not treat each new JNLP file as an application update - only updated jar files will.

This trick gives you complete freedom in what your URL looks like. Example:

<a href=
 "http://localhost/apps/notepad.jsp?dir=c:/carrie/chap1/shower.txt">
 Notepad<a>

This trick, however, has some limitations. Because Web Start will not cache the startup file (aka JNLP descriptor), you cannot run your app offline or through Web Start's app manager.

If you want to include a href attribute in your startup file (aka JNLP descriptor) , read on.


For a live real-world example check out Java Zoom's (MP3 music player with Winamp skins) online JNLP configuration service at http://www.javazoom.net/jlgui/jnlp_configurator.jsp third-party link


There is a limit to what you can do with dynamically generated JNLP files. The combination of codebase and href must exactly specify the JNLP resource that you are retrieving. If you're using a servlet with parameters in a query string to generate the file, it should look like this:

<jnlp spec="1.0+"
      codebase="http://app.datadevelopment.com/app"
      href="MyServlet?param1=value1&param2=value2">

As long as the MIME type returned by the servlet is application/x-java-jnlp-file, Web Start will start just fine. Unfortunately, Web Start will then bomb badly because it tries to use the href attribute as part of the file name for saving the file, and Windows at least doesn't like question marks in a file name. A workaround is to replace the query string with path values:

<jnlp spec="1.0+"
      codebase="http://app.datadevelopment.com/app"
      href="MyServlet/param1=value1/param2=value2">

I'm not 100% sure that this will work with the '=' sign as my application needed only one parameter so I dispensed with the paramN=valueN and replaced the directory with valueN only. The point is, though, that each and every time the application is launched Web Start will go to the web server to get the latest copy of the JNLP and the only way I have found to dynamically generate the content is to append the necessary parameters as path names after the script (JSP in my case, servlet in your case).

If you have multiple parameters and the '=' sign is a problem, strip out the parameter name and require that the parameters be specified in the same order each time. Use one directory delimiter per parameter.

You can use request.getPathInfo() to retrieve the path after your servlet.


Micheal Mandel has posted a servlet that can replace the four macros below in your JNLP startup file.

Macro Description
$$codebase same as Sun's JnlpDownloadServlet macro
$$href same as Sun's JnlpDownloadServlet macro
$$title allows you to dynamically change the app's title - the servlet checks if a parameter in the request URL matches a key for a title defined in the servlet's web.xml config file
$$properties allows you to dynamically add arguments through properties; the servlet adds the request URLs query string parameters as properties to your JNLP startup file (if parse.querystring in the servlet's web.xml config file is set to true)

Macro Usage Example:

<jnlp spec="1.0+" codebase="$$codebase" href="$$href">

  <information>
    <title>$$title</title>
    <offline-allowed/>
  </information>

  <security>
    <all-permissions/>
  </security>

  <resources>
    <j2se version="1.4+ 1.3+"/>
    <jar href="myapp.jar"/>
    $$properties
  </resources>

  <application-desc main-class="MyApp"/>

</jnlp>

You can find Micheal Mandel servlet's source in the appendix.

Q: What values can I use for os and arch?

You can find a list of os and arch values at http://www.vamphq.com/os.html

Q: Can I use native libraries for my apps?

Yes, you can.

To roll a jar with native libs, put all your native libs in the topmost directory ("/"). This results in a flat jar, that is, a jar with no subdirectories except for MANIFEST that carries all that administrative stuff like entry method and cryptographic hashes.

Adding your native libs to the jnlp is not sufficant. You also need to load the libraries in your java code as demanded by the jnlp spec:

It is up to the launched application to actually cause the loading of the library (i.e., by calling System.loadLibrary). Each entry must contain a platform-dependent shared library with the correct naming convention, e.g., *.dll on Windows, or lib*.so on Solaris.

Here is Marc's Java 3D example from Marc's Web Start Kamasutra third-party link post.

public static void main(String[] args) throws Exception
{
  // Note, that Web Start needs explicit native lib loading
  String os = System.getProperty( "os.name" );
  System.out.println("loading " + os + " native libraries ..");
  if( os.startsWith( "Windows" ) )
  {
    // Note, that order matters here
    // load those libs that are required by other libs first

    System.out.print( "j3daudio.dll .. " );
    // drop ".dll" suffix here
    System.loadLibrary( "j3daudio" );
    System.out.println( "OK" );

    System.out.print( "J3D.dll .. " );
    System.loadLibrary( "J3D" );
    System.out.println( "OK" );
  }
  else if( os.equals( "Linux" ) )
  {
    System.out.print( "libj3daudio.so .. " );
    // drop "lib" prefix and ".so" suffix
    System.loadLibrary( "j3daudio" );
    System.out.println( "OK" );

    System.out.print( "libJ3D.so .. " );
    System.loadLibrary( "J3D" );
    System.out.println( "OK" );
  }
  else
   throw new Exception( "OS '" + os + "' not yet supported." );

  [...]
}

Note, two things:

  1. Prefixes and suffixes of the native lib's name have to be removed for the System.loadLibrary call.
  2. Order matters. First pull in the lib with the least dependencies.

Circular Dependency - Known Bug

If you use two libs that depend on each other, your app won't take off no matter what operating system you try (e.g. Linux, Windows, etc.) and you will end up with an unsatisfied link error.

Example: If the lib romeo.dll uses a function in lib julia.dll and julia.dll uses a function in romeo.dll than they depend on each other. No matter which library you load first, e.g.:

System.loadLibrary( "romeo" );   System.loadLibrary( "julia" );
System.loadLibrary( "julia" );   System.loadLibrary( "romeo" );

it will fail. If you start off with System.loadLibrary( "romeo" ), Web Start's class loader will find the library romeo.dll and try to resolve all references. However, Web Start's class loader won't find the library julia.dll as System.loadLibray( "julia" ) hasn't been called yet and julia.dll resides in the Web Start cache under a mangled name and in a directory that is not included in the system path (that is, LD_LIBRARY for Linux or PATH for Windows). You can only break the cycle if you pass in both libraries at once (e.g. System.loadLibrary( new String[] { "romeo", "julia" } )). Unfortunately, this method doesn't exist yet and you're stuck with the circular dependency bug filed at: http://developer.java.sun.com/developer/bugParade/bugs/4491398.html third-party link


Marc van Woerkom suggests a brute-force workaround.

Step 1: Try out the workaround by hand

Step 2: Automate: Create an extension installer that

Q: Can I use my own URLs for downloading JREs?

Yes, Todd Dunst has tried it with IBM's Java runtime 1.3.0 and it works.


Dale Searle's posted the complete sample code for a custom Java Runtime Installer plus a servlet that handles the JNLP HTTP extension protocol. You can find Dale Searle's code reprinted in the appendix plus distilled instructions and comments.


According to the jnlp spec, section 6.4, Web Start uses the extension protocol to request JREs from the server. The jnlp spec tells you what HTTP request will result from a j2se version specification. Like

<j2se version="1.3"
      href="http://www.jrevendor.com/servlet/jreinstaller"/>

leads to a

GET http://www.jrevendor.com/servlet/jreinstaller?
             arch=x86&os=Windows+95&locale=en_US&
             version-id =1.3&known-platforms=1.2

request to the web server.


Here is Todd Dunst's distilled post:

On the web server you need a servlet (e.g. JREInstaller), PHP CGI script or whatever running that decodes the extra URL parameters (arch, locale, version-id, known-platforms) from Web Start's request and returns a JNLP file that describes how to download and start a Java extension installer (e.g. <installer-desc>) that installs the requested Java runtime.

Note, that you can't just return IBM's installer. Instead you have to write your own Java installer as Web Start's Extension Installer service can't handle native installers (.exe) but only works with Java installers.

In order to package the IBM JRE, I installed it to my local machine using IBM's Windows installer and then packed the complete JRE file structure in a single jar (this jar was approx. 17 MB).

Web Start downloads this jar along with another jar containing my custom JNLP installer app to the user's desktop. Web Start starts the JNLP installer app and the JNLP installer app unzips the jar containing IBM's JRE to a configurable directory and uses the JNLP Exension Installer service to to popup a progress dialog to keep the user informed. Finally, the JNLP installer app configures Web Start so that it can to use the newly installed Java runtime.

Once the installer has installed and configured the Java Runtime, control returns to Web Start which starts the app using your newly installed Java runtime. It's all automatic and completely transparenet to the user.


Do I need to sign any of the Jars?

The JRE installer app is no different than any other Web Start app. Therefore, you need to sign all jars to get permission to expand all JRE files on the user's hard drive.

Note, that you need sign the jar holding the compressed JRE as well. If you want to avoid signing all entries in the compressed JRE, you can add the compressed JRE to yet another Jar and sign it. This signs only the compressed JRE jar instead of all its entries.

How do you unpack the JRE Jar file?

Use Java's standard zip/jar classes (java.io.zip.*).

Where do I install the JRE to? How do I tell Web Start to use this newly installed JRE?

Use setJREInfo(platformVersion, jrePath) method of the ExtensionInstallerService.

The first argument (platformVersion) is the actual version of the JRE that you decided to install based on the extra URL parameters sent by Web Start to your JREInstaller servlet. As the requested JRE version may contain wildcards (e.g. <j2se version="1.3+"/>), only you know which JRE version your servlet decided to send back.

The second argument (jrePath) is the path to the JRE executable of your newly installed JRE. This argument consist of the base installation path, plus whatever additional path is necessary to get to the JRE executable. (For Windows, the path may be something like c:\program files\ibm\ibm-jre-1_3_0\bin\javaw.exe. You would build it as follows:

Q: Where can I find JNLP's DTD?

Sun has published JNLP's DTD in the appendix of JNLP's spec (JSR-58).

If you don't want to type it in, you can download a typed-in version at http://www.vamphq.com/download/jnlp-dtd-schema.txt download link

I also created an XML Schema for JNLP available for download at http://www.vamphq.com/download/jnlp-xml-schema.txt download link

To validate your JNLP file, you can use Vamp's validator, code-named Vanessa, that supports DTD, XML Schema, Relax and more. See http://www.vamphq.com/vanessa.html for details.

Q: Can I use Windows UNC names (aka shared network drives) in file:// URLs?

Yes, you can. Dale King figured it out.

If your app's files were in \\foobar\share\directory you would set the codebase URL to codebase="file:////foobar/share/directory".

You can use backslahes if you want, but forward slashes will work and allow you to copy it to Java code without requiring you to escape them. Note that you need four slashes between file: and the machine name.

Q: How can I add arguments to an installer?

An installer doesn't take in arguments, but you can pass on properties achieving the same effect; add properties to your installer's resources section.

Q: Why doesn't 1.3.1_03 work as a Java runtime platform version?

Platform vs. Product versions. Web Sta