Java Web Start includes a servlet in the developer's pack that can
be used to package a JNLP file and its associated resources in a Web Archive
(.war) file. The purpose of the servlet is to provide a simple
and convenient packaging format for JNLP applications, so they can be easily
deployed in a Web Container, such as Tomcat or a J2EE-compliant Application
Server.
The download servlet supports the following features:
Automatic installation of the codebase URL into JNLP files, thus eliminating
manual management of hard-coded URLs into JNLP files.
Explicit specification of the timestamp for a JNLP file,
independent of the file-system timestamp.
Supports all download protocols defined in the JNLP specification
v1.0.1. These include basic download protocol, version-based download
protocol, and extension download protocol.
Version-based information is specified per file or per directory in the Web archive. Thus, no centralized file needs to be managed for the entire archive.
Automatic generation of JARDiff files
The packaging support consists of one servlet: JnlpDownloadServlet.
The servlet is packaged into the jnlp-servlet.jar file.
Below are two examples of how to use the servlet followed by a
detailed description of the functionality of the servlet.
Examples
The first example shows how an application can be packaged into
a WAR file without using the version-based download. The JnlpDownloadServlet
is used to insert the exact URL into the JNLP file at request time. The second
example shows how to add support for version-based download as well.
The JnlpDownloadServlet requires an XML parser in order to work.
If your servlet container is running J2SE 1.4+, there is already a XML
parser integrated in it. Otherwise please add jar files that implement
a Java XML parser to the WEB-INF/lib directory. The
reference implementation of the parser can be downloaded from
http://java.sun.com/xml.
Once the servlet code is available, the Web container must be told to invoke the
servlet on the right set of JNLP and JAR files, or on a given subdirectory. This
is all configured in the WEB-INF/web.xml file inside the <web-app>
tag:
<web-app>
...
</web-app>
The first thing to do is to tell the Web container how to invoke the servlet. This is
done by using the <servlet> tag:
Secondly, the Web container must be told when to invoke the servlet. This can be
done in several ways. It can be invoked for certain directories or for files with
certain extensions. For example, to invoke it for JNLP files, add the following
to the web.xml file:
See also example1 and example2
for examples on how to configure the servlet.
Logging
The servlet has built-in logging capabilities to monitor its behavior. Logging
messages are generated in 4 different categories:
FATAL
A malfunction or internal error happened inside the servlet.
WARNING
An error processing some of the information in the WAR file, e.g., parsing the version.xml file.
INFORMATIONAL
Logging all requests and replies, re-scanning of directories, etc.
DEBUG
Detailed internal information about how a request is processed.
The 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 will
be written to. If no path is specified, logging is done to the standard log for servlets
(using the ServletContext.log method). For example:
The servlet treats JNLP and JAR files specially. JNLP files will be macro-expanded
as described in a section below. A version-based request
for a JAR file might result in the generation for 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. For example:
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 shown below:
The version-based and extension-based download protocols in the JNLP specification allows
a resource to be looked up based on version-id, operating system, system architecture, and
locale. The JnlpDownloadServlet provides two mechanisms for associating this
information with a resource. It can be done on a per-file basis, using a naming convention,
or by a per-directory basis, using a configuration file. Both methods can be used for
the same directory.
The following information can be associated with a resource:
A path to the resource, e.g., /app
A name for the resource, e.g., launch.jnlp
A version-id, e.g., 1.1.0
A list of supported operations systems, e.g., SunOS Linux
A list of supported architectures, e.g., x86
A list of supported locales, e.g., da da_DK
A flag indicating if the version-id is a product version or a platform version (only used for JRE downloading)
The path is specified by the location of the resource in the WAR archive. The rest of the
information is either specified by the use of a naming convention or in the version.xml
file.
Resource Naming
The file naming convention is used if a double underscore (__) marker is found
in the filename. The filename is parsed according to the BNF notation shown
below:
file ::= name __ options . ext
options ::= option ( __ options ) *
option ::= V version-id |
O os |
A arch |
L locale
Only one version-id can be specified per file. However, multiple os, arch, and locale
fields can be specified. For example:
application__V1.2__Len_US__Len.jar
will mean that the resource application.jar has a version-id of 1.2, and the
following associated locales: en_US and en.
The version.xml file
In each directory, a version.xml file can be placed to describe the additional
properties, such as a version-id, for files in that particular directory.
This is an alternative to the file naming convention.
For example, placing the file application-1_2-us.jar in a directory, along
with a version.xml with the following content:
will be the same as having placed the file application__V1.2__Len_US__Len.jar in
the directory.
A resource can also be specified with a platform version-id in the version.xml
file. Such a resource is used to match a particular platform request for a JRE. A resource
with a platform version-id is specified using the <platform> element. For example:
Platform version requests are generated internally by Java Web Start, when an application
has requested a version of the Java 2 platform that is currently not installed on the local system.
The complete document type definition (DTD) for the version.xml is shown in the following:
The JNLP specification defines four different kinds of download requests
that Java Web Start (or more generally, a JNLP Client) can make to
a server when requesting a resource:
Basic Download Request: This is an ordinary URL request to a specific
file. The Last-Modified field of the response is used to determine
if an update is available on the server. The basic download request can be
used for all resource types.
Version-based Download Request: This request type can be used for JAR files
and images, i.e., the following elements will generate a version-based download
request: <jar>, <nativelib>, and <icon>, when
the version attribute is included.
Extension Download Request: This request type is an extension of the
version-based request type and is generated by either the <j2se>
or <extension> elements. In addition to the version information, it
also contains information about operating system, system architecture, and locale.
Platform-version Download Request: This is simliar to the extension download request,
but used to request a particular version of the Java 2 SE Runtime Environment (J2RE). This request
is generated by Java Web Start, when a JNLP file has requested a particular version of the
J2RE that is not currently installed on the client system.
A request is initially processed by the JNLPDownloadServlet, and it extracts the
following information from the request:
Path in WAR file,
Name of requested file
Version string (version-id parameter or platform-version-id parameter)
Current version-id (current-version-id parameter)
List of operation systems (os parameter)
List of architectures (arch parameter)
List of locales (locale parameter)
Consider example2, and assume that it is being hosted at
http://www.mytool.com/tool2/. If the following requests is made:
http://www.mytool.com/tool2/app/lib.jar&version-id=2.1. Then the
path of the resource would be, app/, the name would be lib.jar,
the version string would be 2.1, and the lists for os, architecture, and locales
would be empty.
A request to a directory, e.g., http://www.mytool.com/tool2/app/, will get appended
the default filename: launch.jnlp. Thus, it would be the same as http://www.mytool.com/tool2/app/launch.jnlp.
Handling a basic download request
A request for which no version-id is specified (neither version-id parameter or platform-version-id parameter is
specified in the request) is handled as a basic download request.
The request is first checked to see if it contains a double underscore (__) or is a request to
the version.xml file. If so, the request is rejected and a HTTP 404 error code is returned.
The JnlpDownloadServlet will then try to locate the resource with the given path and name in
the WAR file, and if found return it. If the resource is not found, a HTTP 404 error code is returned for the request.
If a match is found and it is a JNLP file, then it is preprocessed as described below
before returned.
Handling a version-based download request
The resource lookup for resources with a version-id is uniform across the version-based download protocol, the extension
download protocol, and the platform-version download request.
First, the JnlpDownloadServlet will build a database of all the resources that are located in the WAR file
directory that the URL request is accessing (based on the path in the request). The database is built by scanning
the version.xml file (if present), and the list of files in the directory that is using the naming convention
described above. The servlet caches the information internally. It only does a re-scan if the timestamp of the version.xml
file is more recent than at the last scan. Thus, if you add a file using the naming convention, make sure to touch the version.xml
file to force the servlet to do a re-scan.
Secondly, the servlet will scan through the entries in the database to find a match for the given request (the match
rules are described below). For a non-platform request, first the resource entries in the version.xml
file are scanned in the order they are specified, and then secondly the entries that are specified using the naming
convention. For a platform-version request, the platform entries in the version.xml file is scanned
in the order they are specified. If several entries matches the request, then the entry with the
highest version-id is returned. If multiple matches is found with the same highest version-id, then the first one
specified is returned.
The matching rules are as follows:
The name of the resource must match the request
The version-id of the resource must match the version string in the request
For the os, arch, and locale lists the following rules are used:
If an empty list is specified for the resource, then it is a match
If a non-empty list is specified for the resource, then it is a match, if
at least one of the values specified for the resource is a prefix of
at least one of the values specified in the request.
The x-java-jnlp-version-id returned in the response is the version-id for the matching resource, except for a
platform request where it is taken from the <product-version-id> field in the version.xml file.
If a match is found and it is a JNLP file, then it is preprocessed as described below before returned.
Automatic JARDiff generation
The servlet will automatically generate and return 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 (given the above matching rules) and
the request is for a JAR file (e.g., the target resource has the .jar extension), then a JARDiff
file will be generated by the servlet. The JARDiff file is returned as long as 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 given Web
container. The servlet locates the temporary working directory using the javax.servlet.context.tempdir
context attribute.
For example: Consider the example1 WAR file. Lets assume that it has been deployed at the following location: http://www.mytool.com/tool. Thus, a request to http://www.mytool.com/tool/app/launch.jnlp will return the JNLP file. The values of the macro-expanded keys would be:
The servlet does not validate the format of the JNLP file nor that the XML is
well-formed. The value substitution is purely textual.
Explicit Timestamps
An explicit timestamp can be included in a JNLP file to ensure that a consistent
timestamp will be returned from the Web Server. This is especially useful if a JNLP
file is replicated onto multiple Web servers that are serving the same URL in a
round-robin or load-balancing fashion. Note that a similar method is not provided
for JAR files. The version-based download protocol should be used instead.
An explicit timestamp is included in the JNLP if the first-line starts with TS:.
If so, it is parsed accordingly to the ISO 8601 formatting of timestamps (see below). The first line is also removed from the contents.
See example1 and example2 above
for sample JNLP files using the TS: element.