Documentation Contents

< Contents

JnlpDownloadServlet Guide

This section includes the following topics:

Introduction

JnlpDownloadServlet is a servlet that simplifies the process of deploying Java Web Start applications on a web server as well as providing enhanced functionality. JnlpDownloadServlet is available in the sample/jnlp/servlet directory of the JDK, both as compiled JAR files and as source code.

In the simplest case of JNLP deployment, you put your application files and a JNLP file on a web server. After you configure the web server for the JNLP MIME type, you have basic JNLP functionality — the user clicks on a JNLP file link in a browser and your application is downloaded and run.

However, this approach has some drawbacks. First, the explicit URL of the application codebase must appear in the JNLP file. This means it must be changed if you decide to host your application elsewhere, or if you're moving from a local test server to a more public production server. In addition, the file system time stamp on your application files will be used to report the time stamp of your application, which might not be what you want. Finally, only the most basic parts of the JNLP protocol are implemented through HTTP. Versioning and other features are not supported.

Features

JnlpDownloadServlet acts as a liaison between your application files and the client. It provides the following features:

Baseline Example

To understand the useful features that JnlpDownloadServlet brings to application deployment, you must first understand the simplest way an application can be distributed using JNLP and Java Web Start.

The app1 example (in the sample/jnlp/servlet directory of the JDK) contains a simple application and, perhaps more valuable, an Ant build script that builds the application and bundles it in a WAR file for distribution on a web server.

The application itself consists of a single class, Pie, and an image file, key-lime.jpg, which are packaged into the pie.jar JAR file.

The pie.jar archive is packaged into a web application file, app1.war, which has these contents:

WEB-INF/web.xml
index.html
pie.jnlp
pie.jar

The JNLP file describes the application, assuming it is deployed on a server at http://localhost:8080/, which works for a locally installed Tomcat server.

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/app1">
    <information>
        <title>Pie</title>
        <vendor>Example Vendor</vendor>
    </information>
    <resources>
        <j2se version="1.2+"/>
        <jar href="pie.jar" main="true" />
    </resources>
    <application-desc/>
</jnlp>

Consider the interaction between client and server as a dialog:

[User clicks a link in the browser.]

Client browser: May I please have pie.jnlp?

Server: Yes, here you go.

Client browser: I notice the MIME type is application/x-java-jnlp-file. Java Web Start, would you please handle pie.jnlp for me?

Client Java Web Start: Let me see what resources are required for this application. Hey Server, can I please have pie.jar?

Server: Here you go.

Client Java Web Start: Now I'll launch the JAR file using its Main-class manifest attribute.

[Application appears on the user's screen.]

Other Examples

The app2 example shows how to bundle JnlpDownloadServlet with an application and how to use it to perform simple substitutions in a JNLP file.

The app3 example shows how a versioned resource request is handled by JnlpDownloadServlet.

Both app2 and app3 will be referenced from the following sections.

Using JnlpDownloadServlet

To take advantage of JnlpDownloadServlet, perform these steps.

  1. Package JnlpDownloadServlet in your web application WAR file. You must use two JAR files to have the full functionality, jnlp-servlet.jar and jardiff.jar. These two JAR files are put in the WEB-INF/lib directory of your WAR file.
  2. Map requests for *.jnlp and *.jar to JnlpDownloadServlet using your web application's web.xml file. It must contain lines that identify JnlpDownloadServlet and makes it the handler for JNLP and JAR files. Here is a complete example:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE web-app
        PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">
    
    <web-app>
    
      <servlet>
        <servlet-name>JnlpDownloadServlet</servlet-name>
        <servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
        <servlet-name>JnlpDownloadServlet</servlet-name>
        <url-pattern>*.jnlp</url-pattern>
      </servlet-mapping>
    
      <servlet-mapping>
        <servlet-name>JnlpDownloadServlet</servlet-name>
        <url-pattern>*.jar</url-pattern>
      </servlet-mapping>
    
    </web-app>
    

The app2 and app3 examples show how to package JnlpDownloadServlet in a web application. Review the Ant build script app2/build.xml or app3/build.xml for more information.

Substitutions

JnlpDownloadServlet makes convenient substitutions in your JNLP files. When the client requests a JNLP file, the servlet reads the original file, substitutes values, and returns the results.

Time Stamp

If the first line of your JNLP file contains a time stamp, JnlpDownloadServlet uses the value as a time stamp for your application. If you do not specify a time stamp, JnlpDownloadServlet uses the last modified time stamp from the file system.

Using an explicit time stamp is useful if you copy a JNLP file to multiple servers for load balancing. The explicit time stamp ensures that clients see consistent results, regardless of which server they consult.

To use an explicit time stamp, add a line to the top of your JNLP file. Begin the line with TS:. The rest of the line must contain a time stamp in ISO 8601 format, which has this basic format:

YYYY-MM-DD hh:mm:ss

Here is one example:

TS: 2010-08-07 21:19:05

Consult the Reference section for a more complete description of the time stamp string.

Codebase and Other Values

JnlpDownloadServlet makes substitutions for strings that begin with two dollar signs. For example, consider this line in a JNLP file:

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

When a client requests the JNLP file, JnlpDownloadServlet substitutes the correct value for $$codebase, wherever it is deployed. This is convenient because you do not have to hardcode this value in the JNLP file, making it easier to move from server to server.

The full list of substitutions is shown in the following table:

Name Substituted value
$$codebase The URL of the request except for the name of the JNLP file
$$name The name of the JNLP file
$$context The base URL of the web application
$$site The web server address
$$hostname The name of the server

For example, suppose the app2 example is deployed at example.com. The values of each substitution would be as follows:

Name Substituted value
$$codebase http://example.com/app2/
$$name pie.jnlp
$$context http://example.com/app2
$$site http://example.com
$$hostname example.com

The app2/pie.jnlp and app3/pie.jnlp examples use only $$codebase.

Version, Extension, and Platform Requests

The JNLP specification supports requesting application resources with explicit version numbers or resources for certain locales, operating systems, and system architectures. This means that you can deploy an application that has different libraries for different operating systems or different resource files for different locales.

JnlpDownloadServlet provides support for special requests with two different mechanisms. The first is a scheme for naming resource files where locales, operating systems, and other parameters are embedded in the file name. The second mechanism involves an XML file that describes the parameters of resource files in the same directory.

File Naming Convention

JnlpDownloadServlet enables you to specify information about files by embedding it in a file name. If the file name contains two underscores in a row, the file name is treated as containing attributes. A prefix letter specifies the attribute information, as shown here:

Prefix Meaning
V Version number
O Operating system
A Architecture
L Locale

Only one version is allowed per file, but a file can be associated with multiple operating system, architecture, or locale attributes. For example, application__V1.2__Len_US__Len.jar means that the resource application.jar has a version of 1.2, and associated locales of en_US and en.

For example, consider a JNLP file that contains this resource line:

<jar href="app-lib.jar" version="2.0" />

When Java Web Start encounters this line in the JNLP file, it sends a request to the server for version 2.0 of app-lib.jar. If you have placed a file app-lib__V2.0.jar in your web application, JnlpDownloadServlet returns it to the client as version 2.0 of app-lib.jar. Note how the actual file name in your web application gets remapped to be visible to the client as app-lib.jar.

XML Version File

The file naming convention can be cumbersome, especially if you have multiple resource files that each have multiple associations for operating systems, architectures, or locales.

JnlpDownloadServlet supports an alternate mechanism, where all attributes are described in a separate XML file. The servlet looks for a version.xml file in the same directory as the resource. The version.xml file contains information about the other files in the same directory.

For example, the following version.xml file describes a resource that is available to a client as application.jar. The actual file is stored in the same directory as application-1_2-us.jar.

<jnlp-versions>
  <resource>
    <pattern>
      <name>application.jar</name>
      <version-id>1.2</version-id>
      <locale>en_US</locale>
      <locale>en</locale>
    </pattern>
    <file>application-1_2-us.jar</file>
  </resource>
</jnlp-versions>

The app3 example shows how to respond to a versioned request for a resource using the XML version file. In particular, the JNLP file contains this resource line:

<jar href="app-lib.jar" version="2.0" />

The WAR file contains the library, app-lib.jar, and this XML version file version.xml that describes the library:

<jnlp-versions>
  <resource>
    <pattern>
      <name>app-lib.jar</name>
      <version-id>2.0</version-id>
    </pattern>
    <file>app-lib-2.0.jar</file>
  </resource>
</jnlp-versions>

Note how the actual name of the file, app-lib-2.0.jar, is remapped so that the file name visible from the client is app-lib.jar.

Incremental Updates with JARDiff

JnlpDownloadServlet generates and returns incremental updates to JAR files, if possible. If the current-version-id parameter is included in the request, and the servlet can find both a match on the current-version-id and the requested version, and the request is for a JAR file, then a JARDiff file is generated by the servlet. The JARDiff file is returned if its size is less than that of the requested version.

The JARDiff file is generated and stored in a temporary directory that is specific to the web container. The servlet finds the temporary working directory using the javax.servlet.context.tempdir context attribute.

Faster Downloads with Pack200

Pack200 is an efficient compression technology for JAR files. Download and installation times for applications are important factors in how users perceive applications. Making your application resources as small as possible reduces the amount of time users must wait for your application to download.

JnlpDownloadServlet can supply resources for clients, such as Java Web Start, that support GZIP and Pack200 downloads. Place *.jar.pack.gz or *.jar.gz files together with your original *.jar files on the server. For example, JnlpDownloadServlet chooses the best of the following files, based upon what the client supports:

pie.jar
pie.jar.gz
pie.jar.pack.gz

You can create Pack200 files using the pack200 tool that is included with the Java Development Kit. The app3 example creates a Pack200 version of the pie.jar file. Look at build.xml to see how the Pack200 file is created. Because pie.jar is simple, the Pack200 file is negligibly smaller; however, for a larger JAR file, the compression is much greater.

Other Features

JNLP substitutions, Pack200 support, and file attribute support are the most useful features of JnlpDownloadServlet. The servlet also supports a logging system and MIME type mapping.

Logging

The servlet has logging capabilities that enable you to monitor its behavior. Logging messages are generated in different categories:

Logging output is controlled by two servlet initialization parameters, logLevel and logPath. The log level can be set to either NONE, FATAL, WARNING, INFORMATIONAL, or DEBUG. The log path specifies a file where the output is written. If no path is specified, logging is done to the standard log for servlets (using ServletContext.log()). Here is an example:

<servlet>
  <servlet-name>
    JnlpDownloadServlet
  </servlet-name>
  <servlet-class>
    jnlp.sample.servlet.JnlpDownloadServlet
  </servlet-class>

  <init-param>
    <param-name>
      logLevel
    </param-name>

    <param-value>
      DEBUG
    </param-value>
  </init-param>

  <init-param>
    <param-name>
      logPath
    </param-name>

    <param-value>
      /logs/jnlpdownloadservlet.log
    </param-value>
  </init-param>

</servlet>

MIME Types

The servlet treats JNLP and JAR files specially. Substitutions are made in JNLP files as desribed in Substitutions. A version-based request for a JAR file can result in the generation of an incremental update. The servlet uses extensions to determine if a file is a JNLP or JAR file. The default extension of JNLP files is .jnlp and for JAR files is .jar. These default extensions can be overwritten by the initialization parameters: jnlp-extension and jar-extension. Here is an example:

<init-param>
  <param-name>
    jnlp-extension
  </param-name>

  <param-value>
    .xjnlp
  </param-value>
</init-param>

The MIME type that is returned for a file is also based on its extension. The MIME type is looked up in the configuration files for the web container and the WAR file. If no mapping is specified, the default MIME types are assigned:

Extension Default MIME Type
.jnlp application/x-java-jnlp-file
.jar application/x-java-archive
.jardiff application/x-java-archive-diff

To change the MIME type JnlpDownloadServlet returns, use the <mime-type> element in the web.xml file. Here is an example:

<web-app>
   ...
   <mime-mapping>
      <extension>jnlp</extension>
      <mime-type>text/ascii</mime-type>
   </mime-mapping>
   ...
</web-app>

Building JnlpDownloadServlet

Most of the time, you will use JnlpDownloadServlet directly. In rare cases, you might want to add functionality to JnlpDownloadServlet. The full source code is available, and the build is relatively straightforward.

You must have GNU make, a Java Development Kit (JDK), and you must define environment variables. Here is one example on a Linux system.

$ export CLASS_PATH=/home/edmond/Applications/apache-tomcat-7.0.2/lib/servlet-api.jar
$ export FILE_SEPARATOR=:
$ export TMPDIR=/tmp
$ export SDK_HOME=/home/edmond/jdk1.7.0
$ make
.
.
.

The output of the build is lib/jnlp-servlet.jar and lib/jardiff.jar.

References

More Information About ISO 8601 Time Stamps

The general format of a time stamp is:

   YYYY-MM-DD hh:mm:ss

The dashes, colons, and seconds are optional:

   YYYYMMDDhhmm

The hh is in 24-hour notation. By default, the local time zone is used. Universal Time (UTC), also known as GMT time, can be specified by appending the capital letter Z to a time:

     23:59:59Z or 235959Z

The strings +hh:mm, +hhmm, or +hh can be added to the time to indicate that the local time zone is hh hours and mm minutes ahead of UTC. For time zones west of the zero meridian, which are behind UTC, the notation -hh:mm, -hhmm, or -hh is used instead. For example, Central European Time (CET) is +0100 and U.S./Canadian Eastern Standard Time (EST) is -0500. The following strings all indicate the same point in time:

     12:00Z = 13:00+01:00 = 0700-0500

Specification of the XML Version File

The complete document type definition (DTD) for the version.xml file is shown here:

<!ELEMENT jnlp-versions <resource*, platform*)>
<!ELEMENT resource (pattern, file)>
<!ELEMENT platform (pattern, file, product-version-id)>
<!ELEMENT pattern (name, version-id, os*, arch*, locale*)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT version-id (#PCDATA)>
<!ELEMENT os (#PCDATA)>
<!ELEMENT arch (#PCDATA)>
<!ELEMENT locale (#PCDATA)>
<!ELEMENT file (#PCDATA)>
<!ELEMENT product-version-id (#PCDATA)>

Oracle and/or its affiliates Copyright © 1993, 2022, Oracle and/or its affiliates. All rights reserved.
Contact Us