Table of ContentsIntroductionThe next-generation Java Plug-In technology (hereafter the "Java Plug-In") provides support for launching applets directly from JNLP files. Previously, only Java Web Start utilized JNLP files, for the purpose of launching Java applications. Now Java applets can be described using the same meta-descriptor. This new functionality offers many benefits:
This document highlights the slight semantic differences when using JNLP to describe Java applets in the browser, and provides examples of simple and advanced applet deployment via JNLP. Usage
To launch an applet from a JNLP file, use the
<applet width="300" height="300" code="com.mycompany.MyApplet">
<param name="jnlp_href" value="my_applet.jnlp">
</applet>
In this example, my_applet.jnlp is the JNLP descriptor
for the applet. Its contents might look like this:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp href="my_applet.jnlp">
<information>
<title>My Applet</title>
<vendor>My Company, Inc.</vendor>
<offline-allowed />
</information>
<resources>
<j2se version="1.4+"
href="http://java.sun.com/products/autodl/j2se" />
<jar href="my_applet.jar" main="true" />
<extension name="SomeExtension"
href="http://some.server.com/some_extension.jnlp" />
</resources>
<applet-desc
name="My Applet"
main-class="com.mycompany.MyApplet"
width="300"
height="300">
</applet-desc>
</jnlp>
Developers who have used Java Web Start will already be familiar with the JNLP file format. For developers new to JNLP, it is specifed under JSR-56, and described in the context of applications in the Java Web Start Developers' Guide. Semantics
The
Codebase HandlingSpecification
In a JNLP file, the codebase is an optional parameter to the
In the Java Plug-In, a codebase is always provided by the browser, either because it was explicitly specified, or implicitly obtained from the location of the HTML document. This allows relative URLs to be used in JNLP files, which is very useful for moving an entire tree of content from one server to another.
JNLP files reference other JNLP files in a tree structure. The root
JNLP file for a JNLP applet is referenced by an
The rules for codebase computation are as follows:
In simple Java terms, this can be expressed as URL new_codebase = new URL(current_jnlp_dir, current_jnlp_codebase); This codebase computation is not an extension of JSR-56. JSR-56 does not restrict the codebase to be absolute, and therefore it may be relative. ExamplesExample 1:
this JNLP's location: http://www.sun.com/this.jnlp
this JNLP's codebase: http://www.foo.com/test/
resulting codebase for
parsing this JNLP: http://www.foo.com/test/
Example 2:
this JNLP's location: http://www.sun.com/test2/this.jnlp
this JNLP's codebase: <none>
resulting codebase for
parsing this JNLP: http://www.sun.com/test2/
Example 3:
this JNLP's location: http://www.sun.com/this.jnlp
this JNLP's codebase: codebasedir
resulting codebase for
parsing this JNLP: http://www.sun.com/codebasedir
Example 4: Relative paths are used to refer to each nested JNLP, just as in a tree of HTML files.
www.sun.com/html/my_applet.html
refers to: my_applet.jnlp
codebase: www.sun.com/html
my_applet.jnlp:
codebase not specified
inherits "www.sun.com/html"
references JNLP extension "jogl/jogl.jnlp"
jogl/
jogl.jnlp
codebase not specified
inherits "www.sun.com/html/jogl"
(the directory containing jogl.jnlp)
references gluegen-rt/gluegen-rt.jnlp
gluegen-rt/
gluegen-rt.jnlp
codebase not specified
inherits "www.sun.com/html/jogl/gluegen-rt"
(the directory containing gluegen-rt.jnlp)
Best PracticesWe recommend either:
<jnlp> tag in
addition to referring to extension JNLPs using relative URLs quickly
becomes confusing.
Command Line Arguments
The JNLP file syntax supports multiple mechanisms for passing command
line arguments to the JVM. The The new Java Plug-In supports specification of JVM command-line arguments on a per-applet basis, so all of these features of the JNLP file format are supported, with some rules and restrictions. A set of "secure" JVM command-line arguments and system properties is defined in the JNLP File Syntax section of the Java Web Start Developers' Guide. In the new Java Plug-In, by default, only these secure command-line arguments may be specified on a per-applet basis. Non-secure command-line arguments may only be specified on a per-applet basis if:
The concept of a signed JNLP file is described in the JNLP specification, section 5.4.1, "Signing of JNLP Files". These restrictions are necessary for security reasons. The requirement that the JNLP file be signed in order to specify non-secure command-line arguments ensures that the original developer of the applet selected the command-line arguments for the applet.
Note that command-line arguments may still be specified for all
applets via the Java Applet Runtime Settings in the Java Control
Panel. Any command-line arguments specified there are not subject to
the same restrictions as per-applet command-line arguments. In
particular, non-secure arguments like When per-applet JVM command-line arguments are specified, it is likely that the new Java Plug-In will need to launch another JVM instance in order to satisfy them. In other words, it is unlikely that a preexisting JVM instance will have been started with the correct set of command-line arguments to satisfy the current applet's request. The rules for exactly when a new JVM instance is launched to start a given applet are deliberately left unspecified, as this functionality is brand new in the 6u10 release and may need to change in subsequent releases. Here is a rough set of guidelines for the sharing and creation of new JVM instances:
There is no way to "name" a JVM instance used to launch a particular applet and "force" subsequent applets into that JVM instance.
See the section on the
Please provide your feedback if you have comments or questions about this functionality. ExamplesScene Graph DemosThe Scene Graph Demo Applets, courtesy of the Scene Graph development team, illustrate how to use a JNLP extension from within an applet, and how to structure code for easy reuse in both applications and applets. Each of the Scene Graph demos is simply a Component which can be placed in any kind of Container. When run as an application, the demo is placed in a top-level Frame. When run as an applet, the demo is placed in the Applet, which is itself a Container. Most of the Scene Graph demos are also written in a particular style (having a public no-argument constructor) that allows them to be deployed using a generic applet and JNLP file template, specifying which demonstration should be run as a parameter to the applet.
Here is how the
<applet width="200" height="200"
codebase="http://download.java.net/javadesktop/plugin2/scenegraph/"
code="CompatibilityApplet" archive="CompatibilityApplet.jar">
<param name="jnlp_href" value="scenario-applet.jnlp">
<param name="demo.classname" value="demo.alarm.EggTimer">
</applet>
The CompatibilityApplet.jar contains a tiny applet (the source code of
which can be downloaded here)
which simply displays a notice to users of an older version of the
Java Plug-In that this content requires the new Java Plug-In, and
directs them to the download page. Older versions of the Java Plug-In
will use the
The resources of the applet are described in
<jnlp href="scenario-applet.jnlp">
<resources>
<!-- Want some extra RAM since we aim to run
all of these in the same JVM -->
<j2se version="1.6+"
href="http://java.sun.com/products/autodl/j2se"
max-heap-size="128m" />
<extension name="Scenario-0.5"
href="http://download.java.net/javadesktop/scenario/releases/0.5/Scenario-0.5.jnlp"/>
<extension name="AppFramework"
href="http://download.java.net/javadesktop/scenario/demos/lib/AppFramework.jnlp"/>
<jar href="Scenario-Demos.jar" main="true" />
</resources>
<applet-desc
name="Scenario Demo Applet"
main-class="demo.applet.DemoApplet"
width="300" <!-- overridden by applet tag -->
height="300"> <!-- overridden by applet tag -->
</applet-desc>
</jnlp>
Some elements to note:
With this infrastructure, the actual
public class DemoApplet extends JApplet {
public void init() {
try {
Class c = Class.forName(getParameter("demo.classname"));
Object o = c.newInstance();
add((Component) o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
It simply takes in the demo.classname parameter, instantiates the named class reflectively, and adds it to itself. Each of the demos was written to be a Component, which is the key design element which allows the code to be reused trivially in both an applet and an application. JavaFX Script Applet Demo
The JavaFX
applet demonstration, courtesy of JavaFX Technical Lead Chris
Oliver, illustrates how to place JavaFX Script content in an
applet. The base
Once compiled to bytecode, the deployment of the applet is
straightforward. The
<applet width="250" height="280" code="CompatibilityApplet" archive="CompatibilityApplet.jar">
<param name="jnlp_href" value="TimerApplet.jnlp">
</applet>
(See the above example for a description of the backward compatibility applet.) The applet's JNLP file simply refers to the resources for the applet:
<jnlp href="TimerApplet.jnlp">
<resources>
<jar href="TimerApplet.jar" main="true" />
<jar href="javafxrt.jar" />
<jar href="Scenario-0.5.jar" />
</resources>
<applet-desc
name="JavaFX Timer Applet"
main-class="TimerApplet"
width="300"
height="300">
</applet-desc>
</jnlp>
Note that both the NASA World Wind JavaThe NASA World Wind Java applet example, by Patrick Murris of the World Wind Java development team, illustrates how to deploy leading-edge libraries like NASA World Wind Java, as well as how to effectively combine HTML and Java content in a web page using JavaScript.
The web page contains information about the Cascade mountain range
(thanks to Wikipedia) and embeds World Wind Java as an applet to
illustrate the locations of the mountains in the range. Incorporating
World Wind in a web page is remarkably easy. Here is the
<applet id="wwjApplet" width=600 height=380
code="CompatibilityApplet"
archive="CompatibilityApplet.jar">
<param name="jnlp_href" value="WWJApplet.jnlp">
</applet>
The
Here are the relevant portions of the
<jnlp href="WWJApplet.jnlp">
<resources os="Windows">
<property name="sun.java2d.noddraw" value="true"/>
</resources>
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
<jar href="worldwind.jar" main="true" />
<extension name="jogl"
href="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp" />
</resources>
<applet-desc
name="WWJ Applet"
main-class="gov.nasa.worldwind.examples.applet.WWJApplet"
<!-- Overwritten by the surrounding web page -->
width="100"
height="100">
</applet-desc>
</jnlp>
Some items to note:
The HTML links on the web page call JavaScript functions which interact with the applet to navigate it to the appropriate mountain. Here is an example of one of these links: <a href="javascript:gotoLocation(MOUNT_RAINIER);">Mount Rainier</a> (southeast of Tacoma, Washington) ...
When the link is clicked, the JavaScript function
function gotoLocation(locationString) {
var params = locationString.split(';');
if(params.length == 3) // Lat/lon
getWWJApplet().gotoLatLon(parseFloat(params[1]),
parseFloat(params[2]));
...
}
The locations of the mountains are encoded as JavaScript strings in
the HTML of the web page. The latitude, longitude, and other viewing
information is parsed out of these strings and passed into the applet.
The View the page's HTML source code for the full details of this example.
As mentioned above, the preferred method of incorporating World Wind
Java into your application or applet is as a JNLP extension. This
allows the World Wind code resources to be shared among many
applications or applets from around the web which incorporate it. To
reference the World Wind JNLP extension, you would add the following
lines to your application's or applet's JNLP file in the
<extension name="worldwind" href="http://worldwind.arc.nasa.gov/java/0.4.1/webstart/worldwind.jnlp"/>
<extension name="jogl"
href="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"/>
Note that the World Wind extension JNLP is versioned, so you would need to consult the World Wind documentation or visit the forums to find the most current version to reference from your JNLP. The World Wind Central site is a useful source of up-to-date information on World Wind.
Using World Wind as an extension implies that you can not use the
class MyWWJApplet extends WWJApplet {}
Compile this with Jake2: Quake II in JavaThe Jake2 applet example shows the future of game distribution over the Internet. Jake2 is a port of id Software's Quake II to the Java platform developed by Bytonic Software. To date, Jake2 has been deployed very effectively as a Java Web Start application; one click on a JNLP link on the web page launches the game. With the new Java Plug-In, it is now possible to deploy the game directly into the web page with full hardware acceleration and rock-solid reliability. This example shows not only the deployment of advanced 3D game content into the browser, but also how to fully customize the look and branding of the web page and applet, which is important to many web developers.
The
<applet id="jake2Applet" width="800" height="600"
archive="CompatibilityApplet.jar"
code="CompatibilityApplet">
<param name="jnlp_href" value="jake2applet.jnlp">
<param name="image" value="ajax-loader.gif">
<param name="boxborder" value="false">
<param name="centerimage" value="true">
<param name="boxbgcolor" value="#000000">
<param name="boxfgcolor" value="#ffffff">
<!-- Require our own JVM instance for better robustness -->
<param name="separate_jvm" value="true">
<!-- Parameters for the backward compatibility applet -->
<param name="compat_bgcolor" value="#000000">
<param name="compat_fgcolor" value="#ffffff">
</applet>
As before, the Jake2 resources are pulled from a JNLP file,
In this web page we desire the background to be black, and to use a custom
loading indicator before the applet is ready to run rather than the default
Sun logo. The background color of the page is set in the HTML for the page.
An Ajax-style animated GIF (white on black) is used as a loading progress indicator
via the Jake2 was originally designed as an application and sets up some global state
for example in its networking code. It does not work well when two copies of
the code are launched in the same JVM. This is fine for Java Web Start deployment,
but applets typically reuse the same JVM instance. To allow easy redeployment
of Jake2 as an applet, we use the new
The contents of
<jnlp href="jake2applet.jnlp">
<resources os="Windows">
<property name="sun.java2d.noddraw" value="true"/>
</resources>
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
<jar href="jake2.jar" main="true"/>
<extension name="jogl"
href="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp" />
<extension name="joal" href="http://download.java.net/media/joal/webstart/joal.jnlp" />
</resources>
<applet-desc
name="Jake2"
main-class="jake2.Jake2Applet"
<!-- Overridden by the web page -->
width="100"
height="100">
</applet-desc>
</jnlp>
As in the World Wind applet example,
Jake2 uses JOGL and therefore specifies the
Note that the JOGL extension for OpenGL-accelerated 3D graphics and the JOAL extension for spatialized audio via OpenAL are trivially pulled in with one line each in the applet's JNLP file. ConclusionThe introduction of JNLP support in the Java Plug-In opens up many new possibilities for applet deployment and represents a large step forward in the unification of the deployment of Java content both in and out of the browser. Please provide your feedback on this new functionality on the Java Plug-In forum. |