Java(TM) Web Start Developer's Guide

# Developer's Guide

## JavaTM Web Start

### Version 1.2

> This developer's guide provides documentation on how to deploy applications using Java TM Web Start and the JNLP technology.

> Please send comments and feedback to javawebstart-feedback@sun.com.

## Table of Contents

> Java Web Start Technology
> Where to find Java Web Start
> Requirements (desktop and server)
> Setting up the Web site
> Using the Auto-Install Feature
> Application Development Considerations
> Packaging an application for easy deployment
> Converting JNLP files to work with this release
> JNLP File Syntax
> JNLP API Examples
> JNLP API (JavaDoc)

## Java Web Start Technology

> Java Web Start is a helper application that gets associated with a Web browser. When a user clicks on a link that points to a special launch file (JNLP file), it causes the browser to launch Java Web Start, which then automatically downloads, caches, and runs the given Java Technology-based application. The entire process is typically completed without requiring any user interaction, except for the initial single click.

> From a technology standpoint, Java Web Start has a number of key benefits that make it an attractive platform to use for deploying applications:

> - Java Web Start is built exclusively to launch applications written to the Java 2 SE platform. Thus, a single application can be made available on a Web server and then deployed on a wide-variety of platforms, including Windows 98/NT/2000/ME/XP, Linux, and the SolarisTM Operating Environment. The Java platform has proven to be a very robust, productive, and expressive development platform, leading to a significant cost savings due to minimized development and testing costs.
> - Java Web Start supports multiple revisions of the Java 2 platform, Standard Edition. Thus, an application can request a particular version of the platform it requires, such as J2SETM 1.4.0. Several applications can run at the same time on different platform revisions without causing conflicts, and Java Web Start can automatically download and install a revision of the platform if an application requests a version that is not installed on the client system.
> - Java Web Start allows applications to be launched independently of a Web browser. This can be used for off-line operation of an application, where launching through the browser is often inconvenient or impossible. The application can also be launched through desktop shortcuts, making launching the Web-deployed application similar to launching a native application.
> - Java Web Start takes advantage of the inherent security of the Java Platform. Applications are by default run in a protective environment (sandbox) with restricted access to local disk and network resources. It allows the user to safely run applications from sources that are not trusted.
> - Applications launched with Java Web Start are cached locally. Thus, an already-downloaded application is launched on par with a traditionally installed application.
> The technology underlying Java Web Start is the Java TM Network Launching Protocol & API (JNLP). This technology is currently under development via the Java Community Process (JCP). Java Web Start is the reference implementation (RI) for the JNLP specification. The JNLP technology defines, among other things, a standard file format that describes how to launch an application called a JNLP file.

## Where to find Java Web Start

> See the Java Web Start web site, http://java.sun.com/products/javawebstart/, for availability of Java Web Start downloads. The JNLP specification can be found at http://java.sun.com/aboutJava/communityprocess/jsr/jsr_056_jnlp.html.

## Requirements

> ### Desktop/Client requirements

> The client machine requires support for the Java Runtime Environment (JRE), version 1.2.2 or later. Java Web Start is available for Windows 98/NT/2000/ME/XP, the Solaris Operating Environment, and Linux.

> See the README document for details.

> ### Server requirements

> Applications can be deployed from any standard Web server. In order to use Java Web Start, the Web server must be configured with support for a new MIME type as explained below.

## Setting up the Web site

> Java Web Start leverages existing Internet technology, such as the HTTP protocol and Web servers, so existing infrastructure for deploying HTML-based contents can be reused to deploy Java Technology-based applications using Java Web Start.

> In order to deploy your application to client machines, you must make sure that all files containing your application are accessible through a Web server. This typically amounts to copying one or more JAR files, along with a JNLP file, into the Web server's directories. The set-up required for enabling the Web site to support Java Web Start is very similar to deploying HTML-based contents. The only caveat is that a new MIME type needs to be configured for the Web server.

> 1. Configure the Web server to use the Java Web Start MIME type

> Configure the Web server so that all files with the `.jnlp` file extension are set to the `application/x-java-jnlp-file` MIME type.

> Most Web browsers uses the MIME type returned with the contents from the Web server to determine how to handle the particular content. The server must return `application/x-java-jnlp-file` MIME type for JNLP files in order for Java Web Start to be invoked.

> Each Web server has a specific way in which to add MIME types. For example, for the Apache Web server you must add the following line to the `.mime.types` configuration file:

> `application/x-java-jnlp-file JNLP`

> Check the documentation for the specifics of your Web server.

> 2. Create a JNLP file for the application

> The easiest way to create this file is to modify an existing JNLP file to your requirements.

> The syntax and format for the JNLP file is described in a later section.

> 3. Make the application accessible on the Web server

> Ensure your application's JAR files and the JNLP file are accessible at the URLs listed in the JNLP file.

> 4. Create a link from the Web page to the JNLP file

> The link to the JNLP file is a standard HTML link. For example:

> `<a href="MyApp.jnlp">Launch My Application</a>`

> Given the setup in step 1, the Web server will automatically return the `application/x-java-jnlp-file` MIME type with any file with the `.jnlp` extension. This is critical for making sure that a Web browser will launch Java Web Start when downloading the file.

> A link to the Java Web Start installer should also be provided on the Web page, so users who do not already have Java Web Start installed can download and install the software.

> Detecting if Java Web Start is installed

> It is possible to detect if Java Web Start is installed by using a little bit of JavaScript/VBScript in the HTML page. Using this sample script below, a link to an application can be inserted as:

> `<SCRIPT LANGUAGE="Javascript">`
> `<!--`
> `insertLink("http://www.mycompany.com/my-app.jnlp",`
> `"My Application");`
> `// -->`
> `</SCRIPT>`

> Please note that this sample JavaScript cannot detect whether Java Web Start is installed on Gecko-based browsers (for example, Netscape 6.x).

> The `insertLink` method detects if Java Web Start is installed or not. If it is installed, the HTML will be similar to:

> `<a href="http://www.mycompany.com/my-app.jnlp">My Application</a>`

> If Java Web Start is not installed, the following HTML will be emitted:

> `Need to install Java Web Start`

> In a real life situation, this should probably be a link to a download page.

> The sample JavaScript/VBScript is listed below:

>            <!---- This initializes the navigator.family object ---->
>            <SCRIPT LANGUAGE="JavaScript"
>               SRC="xbDetectBrowser.js">
>            </SCRIPT>

> `<SCRIPT LANGUAGE="JavaScript">`
> `var javawsInstalled = 0;`
> `isIE = "false";`

> `if (navigator.mimeTypes && navigator.mimeTypes.length) {`
> `x = navigator.mimeTypes['application/x-java-jnlp-file'];`
> `if (x) javawsInstalled = 1;`
> `} else {`
> `isIE = "true";`
> `}`

> `function insertLink(url, name) {`
> `<!-- Developers should be aware that for Gecko-based browsers (NS 6.x) -->
> <!-- Java Web Start might not be installed ------------------------------>
> if (javawsInstalled || navigator.family == 'gecko') {`
> `document.write("<a href=" + url + ">" + name + "</a>");`
> `} else {`
> `document.write("Need to install Java Web Start");`
> `}`
> `}`
> `</SCRIPT>`

> `<SCRIPT LANGUAGE="VBScript">`
> `on error resume next`
> `If isIE = "true" Then`
> `If Not(IsObject(CreateObject("JavaWebStart.IsInstalled"))) Then`
> `javawsInstalled = 0`
> `Else`
> `javawsInstalled = 1`
> `End If`
> `End If`
> `</SCRIPT>`

> The above sample script invokes the browser detection script `xbDetectBrowser.js`. The content of `xbDetectBrowser.js` is included in this documentation as the file `xbDetectBrowser.html`. It has been reformatted as an HTML file for easy viewing in a browser. To use this script, you would need to strip off the HTML tags and rename the file from `xbDetectBrowser.html` to `xbDetectBrowser.js`.

## Using the Auto-Install Feature

> Version 1.2 of the Java Web Start product enables a "one-click" auto-download and installation mechanism that can improve the user experience of those end users who need to obtain Java Web Start.

> > Note -- This feature is available only for Microsoft Windows platforms.

> To take advantage of this new functionality, developers must implement some scripts on the web pages that host their applications. The scripts determine whether the end-user's browser is Netscape Navigator or Internet Explorer and whether they already have Java Web Start installed on their system. Depending on these determinations, additional script on the application's web page can take action to initiate an automatic download and installation of Java Web Start followed by download and installation of the application.

> ### JavaScript for NetScape Navigator browsers

> The first bit of JavaScript should look something like this:

> >     <SCRIPT LANGUAGE="JavaScript">
> >     var javawsInstalled = 0;
> >     var javaws12Installed = 0;

> >     isIE = "false";

> >     if (navigator.mimeTypes && navigator.mimeTypes.length) {
> >       x = navigator.mimeTypes['application/x-java-jnlp-file'];
> >       if (x) {
> >          javawsInstalled = 1;
> >          javaws12Installed=1;
> >       }
> >     } else {
> >       isIE = "true";
> >     }
> >     </SCRIPT>

> This script determines whether the end-user's browser is an Internet Explorer browser and sets variable `isIE` to `"true"` if so, or to `"false"` if it's a Netscape Navigator browser. If the browser is a Netscape Navigator browser, the script checks the MIME mapping to determine whether any version of Java Web Start is installed. If so, it sets the `javawsInstalled` and `javaws12Installed` variables to `1`. Note that this script cannot distinguish between different versions of Java Web Start that may be installed.

> ### VBScript for Internet Explorer browsers

> The above JavaScript is followed by VBScript that sets variables on Internet Explorer browers:

> >     <SCRIPT LANGUAGE="VBScript">
> >     on error resume next
> >     If isIE = "true" Then
> >       If Not(IsObject(CreateObject("JavaWebStart.isInstalled"))) Then
> >          javawsInstalled = 0
> >       Else
> >          javawsInstalled = 1
> >       End If
> >       If Not(IsObject(CreateObject("JavaWebStart.isInstalled.2"))) Then
> >          javaws12Installed = 0
> >       Else
> >          javaws12Installed = 1
> >       End If
> >     End If
> >     </SCRIPT>

> This VBScript is executed if the variable `isIE` from the preceeding JavaScript is `"true"`, that is, if the end-user's browser is Internet Explorer. This script instantiates the "isInstalled" COM object in `JavaWebStart.dll`, and this object determines two things:
> - Whether the client machine has the latest version (1.2) of Java Web Start installed.
> - Whether the client machine has any version of Java Web Start installed, regardless of version number.
> If Java Web Start 1.2 is installed, the script sets both the `javawsInstalled` and `javaws12Installed` variables to `1`. If only a pre-1.2 Java Web Start product is installed, the script sets `javawsInstalled` to 1 and `javaws12Installed` to `0`. If no version of Java Web Start software is installed, both variables are set to `0`.

> ### Initiating the auto download

> After the above two scripts have been executed, the variables `javawsInstalled` and `javaws12Installed` will be set to either 1 or 0, as follows:

> | `javawsInstalled` | `javaws12Installed`
> Internet Explorer | 1 if any version of Java Web Start is installed; 0 otherwise | 1 if Java Web Start 1.2 is installed; 0 otherwise
> Netscape Navigator | 1 if any version of Java Web Start is installed; 0 otherwise | 1 if any version of Java Web Start is installed; 0 otherwise

> Subsequent JavaScript can use this information to decide whether to initiate an auto-download of the Java Web Start software or simply provide a link to the application's jnlp file. For example (the following sample script assumes that the developer's application is staged on a server with a web address of `www.yyy.zzz`):

> >     <!---- This initializes the navigator.family object ---->
> >     <SCRIPT LANGUAGE="JavaScript"
> >     SRC="xbDetectBrowser.js">
> >     </SCRIPT>

> >     <SCRIPT LANGUAGE="JavaScript">
> >     <!-- Developers should be aware that for Gecko-based browsers (NS 6.x) -->
> >     <!-- Java Web Start might not be installed ------------------------------>
> >     if (javawsInstalled ||  navigator.family == 'gecko') {
> >         document.write("<a href=http://www.yyy.zzz/app.jnlp>Launch
> >             the application</a>");
> >     } else {
> >         document.write("Click ");
> >         document.write("<a href=http://dlres.java.sun.com/PluginBrowserCheck?
> >             pass=http://www.yyy.zzz/download.html&
> >             fail=http://java.sun.com/cgi-bin/javawebstart-platform.sh>here</a> ");
> >         document.write("to download and install the Java Web Start product and
> >             the application.");
> >     }
> >     </SCRIPT>

> (The line breaks following the '?' and '&' are for readability of this code snippet; in actual script there would be no breaks in the href string.)

> The above sample script invokes the browser detection script `xbDetectBrowser.js`. The content of `xbDetectBrowser.js` is included in this documentation as the file `xbDetectBrowser.html`. It has been reformatted as an HTML file for easy viewing in a browser. To use this script, you would need to strip off the HTML tags and rename the file from `xbDetectBrowser.html` to `xbDetectBrowser.js`.

> If the `javawsInstall` is 1, indicating the Java Web Start is already available on the client, then the script provides a link to the application's jnlp file. If Java Web Start is not installed on the client, the script instead provides a link to the PluginBrowserCheck program on the java.sun.com web site. PluginBrowserCheck checks whether the client uses Internet Explorer on a Microsoft Windows platform. If so, PluginBrowserCheck sends the user to `http://www.yyy.zzz/download.html`.

> The `download.html` file is staged by the developer on the server side. It contains special `OBJECT` and `PARAM` tags that will download an auto-installer for Java Web Start to the client machine. Along with Java Web Start, an Active X control will be downloaded to the client. The Active X control will launch the application using the newly installed Java Web Start. Here is a sample `download.html` file:

> >     <HTML>
> >     <BODY>
> >     <OBJECT CODEBASE="http://java.sun.com/products/javawebstart/autodl/jinstall_javaws-1_2-windows-i586.cab"
> >     CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74
> >     284" HEIGHT=0 WIDTH=0>
> >     <PARAM NAME="app" VALUE="http://www.yyy.zzz/app.jnlp">
> >     <PARAM NAME="back" VALUE="true">
> >     <!-- Alternate HTML for browsers which cannot instantiate the object -->
> >     <A HREF="http://java.sun.com/cgi-bin/javawebstart-platform.sh?">
> >     Download Java Web Start</A>
> >     </OBJECT>
> >     </BODY>
> >     </HTML>

> This `OBJECT` tag fetches a cab file that contains an auto-installer for Java Web Start 1.2. The cab file does not contain a Java Runtime Environment, so you will need to have a Java Runtime Environment installed before using this auto-download feature. The `PARAM` tags specify the location of the application's jnlp file so that it may be automatically launched after Java Web Start is installed on the client.

> Referring back to the JavaScript sample: If the PluginBrowserCheck determines that the end-user is not using Internet Explorer on Microsoft Windows, the end-user will be redirected to a shell script on java.sun.com that will call up an appropriate manual download page for Java Web Start.

## Application Development Considerations

> Developing applications that can be deployed with Java Web Start are generally the same as developing a stand-alone application for the Java 2 platform. Hence, the entry point for the application is the standard `public static void main(String[] argv)`.

> However, in order to support Web deployment -- automatic download and launching of the application -- and to ensure that an application can run in a secure sandbox, there are a few added considerations:

> - An application must be delivered as a set of JAR files.
> - All application resources, such as files and images must be stored in JAR files; and they must be referred to using the `getResource` mechanism in the Java 2 platform (see below).
> - If an application is written to run in a secure sandbox, it must follow these restrictions:
> - No access to local disk.
> - All JAR files must be downloaded from the same host.
> - Network connections are enabled only to the host from which the JAR files are downloaded.
> - No security manager can be installed.
> - No native libraries.
> - Limited access to system properties. The application has read/write access to all system properties defined in the JNLP File, as well as read-only access to the same set of properties than an Applet has access to.

> An application is allowed to use the `System.exit` call.

> - An application that needs unrestricted access to the system will need to be delivered in a set of signed JAR files. All entries in each JAR file must be signed.

> ### Retrieving Resources from JAR files

> Java Web Start only transfers JAR files from the Web server to the client machine. It determines where to store the JAR files on the local machine. Thus, an application cannot use disk-relative references to resources such as images and configuration files.

> All application resources must be retrieved from the JAR files specified in the `resources` section of the JNLP file, or retrieved explicitly using an HTTP request to the Web server. We recommend storing resources in JAR files, since they will be cached on the local machine by Java Web Start.

> The following code example shows how to retrieve images from a JAR file:

> `// Get current classloader`
> `ClassLoader cl = this.getClass().getClassLoader();`
> `// Create icons`
> `Icon saveIcon = new ImageIcon(cl.getResource("images/save.gif"));`
> `Icon cutIcon = new ImageIcon(cl.getResource("images/cut.gif"));`
> `...`

> The example assumes that the following entries exist in one of the JAR files for the application:

> `images/save.gif`
> `images/cut.gif`

> ### Security and Code Signing

> Java Web Start addresses the security issues of:
> - Protecting users against malicious code (intentional & unintentional) that may affect local files
> - Protecting enterprises against code that may attempt to access or destroy data on networks
> Applications launched with Java Web Start are -- by default -- run in a restricted environment where they have limited access to local computing resources, such as storage devices and the local network. In this sandbox environment, Java Web Start can guarantee that a downloaded and potentially untrusted application cannot compromise the security of the local files or the network.

> An additional security feature supported by Java Web Start is digital code signing. If an application being invoked is delivered in one or more signed JAR files, Java Web Start will verify that the contents of the JAR file have not been modified since they were signed. If verification of a digital signature fails, Java Web Start will not run the application, since it may have been compromised by a third-party.

> The support for code signing is important for both users and for application service providers. This service makes it possible for users to verify that an application comes from a trusted source. Because the application service provider signs the code, both can be ensured that no other party can impersonate the application on the Web. A signed application that is trusted by the user can also request additional system privileges, such as access to a local disk.

> Java Web Start presents a dialog displaying the application's origin, based on the signer's certificate, before the application is launched. Thereby allowing the user to make an informed decision whether to grant additional privileges to the downloaded code, or not.

> An application can request full access to a client system when all its JAR files are signed by including the following settings in the JNLP file:

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

> The implementation of code signing in Java Web Start is based on the security API in the core Java 2 Platform. The Java 2 SE JRE 1.2.x supports code signing with the SHAwithSDA algorithm. Java 2 SE JRE 1.3 also supports MD2withRSA and MD5withRSA. The MD5withRSA is currently the most often used algorithm.

> Developers sign code for use with Java Web Start in the same manner as for Java Applets by using the standard `jarsigner` tool from the Java 2 SE SDK. The documentation for the `jarsigner` tool provides examples on how to sign code, create test certificates, and other signing related issues.

> Java Web Start also support use of the Netscape `signtool` when used with the Java 2 SE JRE 1.3.0. See the Netscape Web site for details: http://developer.netscape.com/software/signedobj/

> ### Signing JAR Files with a Test Certificate

> Here are the steps needed to sign a JAR file with a test certificate:

> 1. Make sure that you have a JDK 1.2 or JDK 1.3 keytool and jarsigner in your path (located in the J2SE SDK bin directory).

> 2. Create a new key in a new keystore as follows:

>    > `keytool -genkey -keystore myKeystore -alias myself`

>    You will get prompted for a information about the new key, such as password, name, etc. This will create the myKeystore file on disk.

> 3. Then, create a self-signed test certificate as follows:

>    > `keytool -selfcert -alias myself -keystore myKeystore`

>    This will prompt for the password. Generating the certificate takes a few minutes.

> 4. Check to make sure that everything is ok. To list the contents of the keystore, use the command:

>    > `keytool -list -keystore myKeystore`

>    It should list something like:

>    > `Keystore type: jks
>    > Keystore provider: SUN
>    > Your keystore contains 1 entry:
>    > myself, Tue Jan 23 19:29:32 PST 2001, keyEntry,
>    > Certificate fingerprint (MD5):
>    > C2:E9:BF:F9:D3:DF:4C:8F:3C:5F:22:9E:AF:0B:42:9D
>    > `

> 5. Finally, sign the JAR file with the test certificate as follows:

>    > `jarsigner -keystore myKeystore test.jar myself`

>    Repeat this step on all of your JAR files.

> Please note that a self-signed test certificate should only be used for internal testing, since it does not provide any guarantees about the identity of the user and therefore cannot be trusted. A trust-worthy certificate can be obtained from a certificate authority, such as VeriSign, and should be used when the application is put into production.

> ### How to Encode JNLP Files in UTF-8

> Beginning with Java Web Start version 1.2, JNLP files may be encoded in any character encoding supported by the J2SE platform. (See the J2SE documentation for a list of supported encodings.)

> Specify an encoding in the XML prolog of the JNLP file. For example, the following line indicates that the JNLP file will be encoded in UTF-16.

> >     <?xml version="1.0" encoding="utf-16"?>

> The XML prolog itself must be UTF-8 encoded.

## Packaging an application for easy deployment

> The Developer's Pack contains a servlet that can be used to bundle a JNLP-deployed application in a Web Archive (WAR) file. See Packaging JNLP Applications in a Web Archive

## Converting JNLP files to work with this release

> The JNLP file format has not changed between the 1.0 and this release.

> If your JNLP file is compatible with a version of Java Web Start that is lower than 1.0, please note that the JNLP file format has changed significantly. Below is a list of the most common modifications that needs to be applied to a 0.4 JNLP file to make it compatible with Java Web Start 1.0 or higher:

> - Set `spec` attribute to 1.0.
> - Rename the `unrestricted` element to `all-permissions`.
> - Rename the `jre` element to `j2se` and move this element inside the `resources` element (i.e., make `j2se` a subelement of `resources`).

> Converting JNLP files used with the 1.0-beta or 1.0-rc release only requires updating the `spec` attribute to "1.0".

##

## JNLP File Syntax

> The format used in this release correspond to the format specified in the Java Network Launching Protocol and API (JNLP) Specification, v1.0. This document describes the most commonly used elements of the JNLP file. Refer to the specification for a complete description of the format.

> The JNLP file is an XML document. The following shows a complete example of a JNLP file:

> `<?xml version="1.0" encoding="utf-8"?>`
> `<!-- JNLP File for SwingSet2 Demo Application -->`
> `<jnlp`
> `spec="1.0+"`
> `codebase="http://javaweb.eng.com/jaws/apps"`
> `href="swingset2.jnlp">`
> `<information>`
> `<title>SwingSet2 Demo Application</title>`
> `<vendor>Sun Microsystems, Inc.</vendor>`
> `<homepage href="docs/help.html"/>`
> `<description>SwingSet2 Demo Application</description>`
> `<description kind="short">A demo of the capabilities of the Swing Graphical User Interface.</description>`
> `<icon href="images/swingset2.jpg"/>`
> `<icon kind="splash" href="images/splash.gif"/>`
> `<offline-allowed/>`
> `</information>`
> `<security>`
> `<all-permissions/>`
> `</security>`
> `<resources>`
> `<j2se version="1.3"/>`
> `<jar href="lib/SwingSet2.jar"/>`
> `</resources>`
> `<application-desc main-class="SwingSet2"/>`
> `</jnlp>`

> The example shows the basic outline of the document. The root element is `jnlp`, which has four subelements: `information`, `security`, `resources`, and `application-desc`. In addition, Java Web Start also supports launching Applets by using the `applet-desc` element. The elements are described in more detail below.

> ### The JNLP Element

> spec attribute: This attribute must be 1.0 or higher to work with this release. The default value is "1.0+". Thus, it can typically be omited.

> codebase attribute: All relative URLs specified in `href` attributes in the JNLP file is using this URL as a base.

> href attribute: This is a URL pointing to the location of the JNLP file itself. Java Web Start requires this attribute to be set in order for the application to be included in the Application Manager.

> ### The Information Element

> title element: The name of the application.

> vendor element: The name of the vendor of the application.

> homepage element: Contains a single attribute, `href`, which is a URL locating the home page for the Application. It is used by the Application Manager to point the user to a Web page where they can find more information about the application.

> description element: A short statement about the application. Description elements are optional. The `kind` attribute defines how the description should be used, it can have one of the following values:

> - one-line: If a reference to the application is going to appear on one row in a list or a table, this description will be used.
> - short: If a reference to the application is going to be displayed in a situation where there is room for a paragraph, this description is used.
> - tooltip: A description of the application intended to be used as a tooltip.
> Only one description element of each kind can be specified. A description element without a kind is used as a default value. Thus, if Java Web Start needs a description of kind short, and it is not specified in the JNLP file, then the text from the description without an attribute is used

> All descriptions contain plain text. No formatting, such as HTML tags is supported.

> icon element: Contains an HTTP URL to an image file in either GIF or JPEG format. The icons are used to represents the application when Java Web Start presents the application to the user during launch, in the Application Manager, and in desktop shortcuts. A 64x64 icon is shown during download and a 32x32 for desktop icons and in the application manager. Java Web Start automatically resizes an icon to the appropriate size.

> Optional `width` and `height` attributes can be used to indicate the size of the images.

> The optional `kind="splash"` attribute may be used in an icon element to indicate that the image is to be used as a "splash" screen during the launch of an application. If the JNLP file does not contain an `icon` element with a `kind="splash"` attribute, but does contain another `icon` tag, Java Web Start will display a splash screen consisting of the image specified by the `icon` element on the left and the application's title and vendor on the right.

> If the JNLP file does not contain any `icon` images, the splash image will consist of the application's title and vendor, as taken from the JNLP file.

> Splash images will be surrounded by a border defined by Java Web Start.

> The first time an application is launched following the addition or modification of the `icon` element in the JNLP file, the old splash image will still be displayed. The new splash image will appear on the second and subsequent launches of the application.

> offline-allowed element: The optional `offline-allowed` element indicates if the application can be launched offline.

> Applications that are not marked offline in the JNLP file will not be able to be launched through the Application Manager, if the offline checkbox is checked. The default is that an application only works if the client system is online.

> The `offline-allowed` element also controls how Java Web Start checks for an update to an application. If the element is not specified, i.e., the application is required to be online to run, Java Web Start will always do a check for an updated version before the application is launched. And if an update is found, the new application will be downloaded and launched. Thus, the user is guaranteed to always be running the latest version of the application. However, the application will not be able to run offline.

> If `offline-allowed` is specified, Java Web Start will also try to see if an update is available. However, if the application is already downloaded, then this check will timeout after a few seconds, and in that case the cached application will be launched instead. Thus, in this situation, given a reasonable fast server connection, the user will in most cases run the lastest version of the application, but it is not guaranteed. However, offline launching is supported.

> ### The Security Element

> Each application is, by default, run in a restricted execution environment, similar to the Applet sandbox. The security element can be used to request unrestricted access.

> If the `all-permissions` element is specified, the application will have full access to the client machine and local network. If an application requested full access, then all JAR files must be signed. The user will be prompted to accept the certificate the first time the application is launched.

> ### The Resources Element

> The `resources` element is used to specify all the resources, such as Java class files, native libraries, and system properties, that are part of the application. A resource definition can be restricted to a specific operating system, architecture, or locale using the `os`, `arch`, and `locale` attributes.

> The resources element has 6 different possible subelements: `jar`, `nativelib`, `j2se`, `property`, `package`, and `extension`. The `package` and `extension` elements are not discussed in this developer's guide. See specification for details.

> A `jar` element specifies a JAR file that is part of the application's classpath. For example:

> `<jar href="myjar.jar"/>`

> The `jar` file will be loaded into the JVM using a `ClassLoader` object. The `jar` file will typically contain Java classes that contain the code for the particular application, but can also contain other resources, such as icons and configuration files, that are available through the `getResource` mechanism.

> A `nativelib` element specifies a JAR file that contains native libraries. For example:

> `<nativelib href="lib/windows/corelib.jar"/>`

> The JNLP Client must ensure that each file entry in the root directory of the JAR file (i.e., /) can be loaded into the running process using the `System.loadLibrary` method. Each entry must contain a platform-dependent shared library with the correct naming convention, e.g., *.dll on Windows, or lib*.so on Solaris/Linux. The application is responsible for doing the actual call to `System.loadLibrary`.

> Native libraries would typically be included in a `resources` element that is guarded against a particular operating system and architecture. For example:

> `<resources os="SunOS" arch="sparc">`
> `<nativelib href="lib/solaris/corelibs.jar"/>`
> `</resource>`

> By default, `jar` and `nativelib` resources will be downloaded eagerly, i.e., they are downloaded and available locally to the JVM running the application before the application is launched. The `jar` and `nativelib` elements also allow a resource to be specified as `lazy`. This means that the resource does not necessarily need to be downloaded onto the client system before the application is launched.

> The `download` attribute is used to control whether a resource is downloaded eagerly or lazily. For example:

> `<jar href="sound.jar" download="lazy"/>`
> `<nativelib href="native-sound.jar" download="eager"/>`

> The `j2se` element specifies what Java 2 SE Runtime Environment (JRE) versions an application is supported on, as well as standard parameters to the Java Virtual Machine. Several JREs can be specified, which indicates a prioritized list of the supported JREs, with the most preferred version first. For example:

> `<j2se version="1.3" initial-heap-size="64m"/>`
> `<j2se version="1.2"/>`

> The `version` attribute refers to, by default, a particular revision of the Java 2 platform. Current defined revisions are "1.2" and "1.3". The JNLP specification also allows specifying exact product versions, such as the Java 2 JRE 1.2.2-001 by Sun Microsystems, Inc.

> Java Web Start does not consider a non-FCS JRE to match a request for a particular platform version. For example, a request of the form `<j2se version="1.4+">` does not consider an installed "1.4.0-beta" JRE as a match for the request. A JRE from Sun Microsystems, Inc. is by convention (starting from 1.3.0) a non-FCS if there is a dash (-) in the product version string. An application wishing to run under any beta J2RE must explicitly specify a product version, i.e., also using the `href` attribute in the `j2se` element. For example, a proper request for a beta JRE:
> <`j2se version="1.4-beta" href="http://java.sun.com/products/autodl/j2se"/>`

> The `property` element defines a system property that will be available through the `System.getProperty` and `System.getProperties` methods. It has two required attributes: `name` and `value`. For example:

> `<property name="key" value="overwritten"/>`

> ### The Application-Desc Element

> The `application` element indicates that the JNLP file is launching an application (as opposed to an Applet). The application element has an optional attribute, `main-class`, which can be used to specify the name of the application's main class, i.e., the class that contains the `public static void main(String argv[])` method where execution must begin.

> The main-class attribute can be omitted, if the first JAR file specified in the JNLP File contains a manifest file containing the main class.

> Arguments can be specified to the application be including one or more nested `argument` elements. For example:

> `<application-desc main-class="Main">`
> `<argument>arg1</argument>`
> `<argument>arg2</argument>`
> `</application-desc>`

> ### The Applet-Desc Element

> Java Web Start has support for launching Java Applets. This support provides easy migration of existing code to Java Web Start.

> An Applet is launched using the `applet-desc` element instead of the `application-desc` element. For example:

> `<applet-desc`
> `documentBase="http://..."`
> `name="TimePilot"`
> `main-class="TimePilot.TimePilotApp"`
> `width="527"`
> `height="428">`
> `<param name="key1" value="value1"/>`
> `<param name="key2" value="value2"/>`
> `</applet-desc>`

> The JAR files that make up the Applet are described using the `resources` element as for applications. The `documentBase` must be provided explicitly since a JNLP file is not embedded in an HTML page. The rest of the attributes correspond to the respective HTML applet tag elements.

> The `main-class` attribute is used instead of the `code` attribute. The `main-class` attribute is assigned the name of the `Applet` class (without the `.class` extension). This attribute can be omitted if the `Applet` class can be found from the `Main-Class` manifest entry in the main JAR file.

> Note: Applets must be packaged in JAR files in order to work with Java Web Start.

##

## JNLP API Examples

> The JNLP API is designed to provide additional information to the application that would otherwise not be available using the standard Java 2 SE API. The following code examples show how the following services can be used: `BasicService`, `ClipboardService`, `DownloadService`, `FileOpenService`, `FileSaveService`, `PrintService`, and `PersistenceService`.

> The public classes and interfaces in the JNLP API are included in the `jnlp.jar` file. This JAR file must be included in the classpath when compiling source files that use the JNLP API. For example (on Windows):

> `javac -classpath .;jnlp.jar *.java`

> The `jnlp.jar` file is included in the JNLP Developers Pack.

> ### Using a BasicService Service

> The javax.jnlp.BasicService service provides a set of methods for querying and interacting with the environment similar to what the `AppletContext` provides for a Java Applet.

> The `showURL` method uses the JNLP API to direct the default browser on the platform to show the given URL. The method returns true if the request successes, otherwise false.

> `import javax.jnlp.*;`
> `...`

> `// Method to show a URL`
> `boolean showURL(URL url) {`
> `try {`
> `// Lookup the javax.jnlp.BasicService object`
> `BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");`
> `// Invoke the showDocument method`
> `return bs.showDocument(url);`
> `} catch(UnavailableServiceException ue) {`
> `// Service is not supported`
> `return false;`
> `}`
> `}`

> ### Using a ClipboardService Service

> The `javax.jnlp.ClipboardService` service provides methods for accessing the shared system-wide clipboard, even for applications that are running in the restricted execution environment.

> Java Web Start will warn the user of the potential security risk of letting an untrusted application access potentially confidential information stored in the clipboard, or overwriting contents stored in the clipboard.

> `import javax.jnlp;`
> `...`

> `private ClipboardService cs;`

> `try {`
> `cs = (ClipboardService)ServiceManager.lookup`
> `("javax.jnlp.ClipboardService");`
> `} catch (UnavailableServiceException e) {`
> `cs = null;`
> `}`

> `if (cs != null) {`
> `// set the system clipboard contents to a string selection`
> `StringSelection ss = new StringSelection("Java Web Start!");`
> `cs.setContents(ss);`
> `// get the contents of the system clipboard and print them`
> `Transferable tr = cs.getContents();`
> `if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {`
> `try {`
> `String s = (String)tr.getTransferData(DataFlavor.stringFlavor);`
> `System.out.println("Clipboard contents: " + s);`
> `} catch (Exception e) {`
> `e.printStackTrace();`
> `}`
> `}`
> `}`

> ### Using a DownloadService Service

> The javax.jnlp.DownloadService service allows an application to control how its own resources are cached.

> The service allows an application to determine which of its resources are cached, to force resources to be cached, and to remove resources from the cache.

>     import javax.jnlp.*;
>         ...

>         DownloadService ds;

>         try {
>             ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
>         } catch (UnavailableServiceException e) {
>             ds = null;
>         }

>         if (ds != null) {

>             try {
>                 // determine if a particular resource is cached
>                 URL url =
>                         new URL("http://java.sun.com/products/javawebstart/lib/draw.jar");
>                 boolean cached = ds.isResourceCached(url, "1.0");
>                 // remove the resource from the cache
>                 if (cached) {
>                     ds.removeResource(url, "1.0");
>                 }
>                 // reload the resource into the cache
>                 DownloadServiceListener dsl = ds.getDefaultProgressWindow();
>                 ds.loadResource(url, "1.0", dsl);
>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

> ### Using a FileOpenService Service

> The javax.jnlp.FileOpenService service provides methods for importing files from the local disk, even for applications that are running in the restricted execution environment.

> This interface is designed to provide the same kind of of disk access to potentially untrusted Web-deployed applications that a Web developer has when using HTML. HTML forms support the inclusion of files by displaying a file open dialog.

>     import javax.jnlp.*;
>         ...

>         FileOpenService fos;

>         try {
>             fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
>         } catch (UnavailableServiceException e) {
>             fos = null;
>         }

>         if (fos != null) {
>             try {
>                 // ask user to select a file through this service
>                 FileContents fc = fos.openFileDialog(null, null);
>                 // as user to select multiple files through this service
>                 FileContents [] fcs = fos.openMultiFileDialog(null, null);
>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

> ### Using a FileSaveService Service

> The javax.jnlp.FileSaveService service provides methods for exporting files to the local disk, even for applications that are running in the restricted execution environment.

> This interface is designed to provide the same level of disk access to potentially untrusted Web-deployed applications that a Web browser provides for contents that it is displaying. Most browsers provide a Save As... dialog as part of their user interface.

>     import javax.jnlp.*;
>         ...

>         FileSaveService fss;
>         FileOpenService fos;

>         try {
>             fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
>             fss = (FileSaveService)ServiceManager.lookup
>                                        ("javax.jnlp.FileSaveService");
>         } catch (UnavailableServiceException e) {
>             fss = null;
>             fos = null;
>         }

>         if (fss != null && fos != null) {
>             try {
>                 // get a file with FileOpenService
>                 FileContents fc = fos.openFileDialog(null, null);
>                 // one way to save a file
>                 FileContents newfc = fss.saveFileDialog(null, null,
>                 fc.getInputStream(), "newFileName.txt");
>                 // another way to save a file
>                 FileContents newfc2 = fss.saveAsFileDialog(null, null, fc);

>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

> Also see Using FileContents.

> ### Using a PrintService Service

> The javax.jnlp.PrintService service provides methods for accessing to printing even for applications that are running in the restricted execution environment.

> Using this service, an application can submit a print job. Java Web Start will then show this request to the user, and if accepted queue the request to the printer.

>     import javax.jnlp.*;
>         ...

>         PrintService ps;

>         try {
>             ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");
>         } catch (UnavailableServiceException e) {
>             ps = null;
>         }

>         if (ps != null) {
>             try {

>                 // get the default PageFormat
>                 PageFormat pf = ps.getDefaultPage();

>                 // ask the user to customize the PageFormat
>                 PageFormat newPf = ps.showPageFormatDialog(pf);

>                 // print the document with the PageFormat above
>                 ps.print(new DocToPrint());

>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

>         // Code to construct the Printable Document
>         class DocToPrint implements Printable {
>             public int print(Graphics g, PageFormat pageformat, int PageIndex){
>                 // code to generate what you want to print
>             }
>         }

> ### Using a PersistenceService Service

> The javax.jnlp.PersistenceService service provides methods for storing data locally on the client system, even for applications that are running in the restricted execution environment.

> The service is designed to be (somewhat) similar to that which the cookie mechanism provides to HTML-based applications. Cookies allow a small amount of data to be stored locally on the client system. That data can be securely managed by the browser and can only be retrieved by HTML pages which originate from the same URL as the page that stored the data.

>     import javax.jnlp.*;
>         ...

>         PersistenceService ps;
>         BasicService bs;

>         try {
>             ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService");
>             bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
>         } catch (UnavailableServiceException e) {
>             ps = null;
>             bs = null;
>         }

>         if (ps != null && bs != null) {

>             try {
>                 // find all the muffins for our URL
>                 URL codebase = bs.getCodeBase();
>                 String [] muffins = ps.getNames(url);

>                 // get the attributes (tags) for each of these muffins.
>                 // update the server's copy of the data if any muffins
>                 // are dirty
>                 int [] tags = new int[muffins.length];
>                 URL [] muffinURLs = new URL[muffins.length];
>                 for (int i = 0; i < muffins.length; i++) {
>                     muffinURLs[i] = new URL(codebase.toString() + muffins[i]);
>                     tags[i] = ps.getTag(muffinURLs[i]);
>                     // update the server if anything is tagged DIRTY
>                     if (tags[i] == PersistenceService.DIRTY) {
>                         doUpdateServer(muffinURLs[i]);
>                     }
>                 }

>                 // read in the contents of a muffin and then delete it
>                 FileContents fc = ps.get(muffinURLs[0]);
>                 long maxsize = fc.getMaxLength();
>                 byte [] buf = new byte[fc.getLength()];
>                 InputStream is = fc.getInputStream();
>                 long pos = 0;
>                 while((pos = is.read(buf, pos, buf.length - pos)) > 0) {
>                     // just loop
>                 }
>                 is.close();

>                 ps.delete(muffinURLs[0]);

>                 // re-create the muffin and repopulate its data
>                 ps.create(muffinURLs[0], maxsize);
>                 fc = ps.get(muffinURLs[0]);
>                 // don't append
>                 OutputStream os = fc.getOutputStream(false);
>                 os.write(buf);
>                 os.close();

>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

>        void doUpdateServer(URL url) {
>             // update the server's copy of the persistent data
>             // represented by the given URL
>             ...
>             ps.setTag(url, PersistenceService.CACHED);
>        }

> ### Using FileContents

> `FileContents` objects encapsulate the name and contents of a file. An object of this class is used by the `FileOpenService,` `FileSaveService` and`PersistenceService`. Here is an example of how an instance of a `FileContents` can be used to read from and write to a file:

>     import javax.jnlp.*;
>         ...

>         FileOpenService fos;

>         //Initialize fos (see Using a FileOpenService Service example)
>         ...

>         if (fos != null) {

>             try {

>                 // get a FileContents object to work with from the
>                 // FileOpenService
>                 FileContents fc = fos.openFileDialog(null, null);

>                 // get the InputStream from the file and read a few bytes
>                 byte [] buf = new byte[fc.getLength()];
>                 InputStream is = fc.getInputStream();
>                 int pos = 0;
>                 while ((pos = is.read(buf, pos, buf.length - pos)) > 0) {
>                     // just loop
>                 }
>                 is.close();

>                 // get the OutputStream and write the file back out
>                 if (fc.canWrite()) {
>                    // don't append
>                    OutputStream os = fc.getOutputStream(false);
>                    os.write(buf);
>                 }

>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

> ### Using a JNLPRandomAccessFile

> Instances of `JNLPRandomAccessFile` support both reading and writing to a random access file. A random access file behaves like a large array of bytes stored in the file system. Here is an example of how an instance of a JNLPRandomAccessFile can be used to write to a random access file:

>     import javax.jnlp.*;
>         ...

>         FileOpenService fos;

>         //Initialize fos (see Using a FileOpenService Service example)
>         ...

>         if (fos != null) {
>             try {
>                // ask the user to choose a file to open
>                FileContents fc = fos.openFileDialog(null, null);

>                // attempt to increase the maximum file length
>                long grantedLength = fc.getLength();
>                if (grantedLength + 1024 > fc.getMaxLength()) {
>                    // attempt to increase the maximum file size defined by
>                    // the client
>                    grantedLength = fc.setMaxLength(grantedLength + 1024);
>                }

>                // if we were able to increase the maximum allowable file size,
>                // get a JNLPRandomAccessFile representation of the file, and
>                // write to it
>                if (fc.getMaxSize() > fc.getLength() && fc.canWrite()) {
>                    JNLPRandomAccessFile raf = fc.getRandomAccessFile("rw");
>                    raf.seek(raf.length() - 1);
>                    raf.writeUTF("Java Web Start!");
>                    raf.close();
>                }
>             } catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }

Please send comments and feedback to javawebstart-feedback@sun.com. | Copyright © 2002, Sun Microsystems, Inc. All rights reserved.