5.2 Developing and Deploying Java Web Start Applications

«« Previous
Next »»

Java Web Start


Java Web Start software provides the power to launch full-featured applications with a single click. Users can download and launch applications, such as a complete spreadsheet program or an Internet chat client, without going through lengthy installation procedures.

With Java Web Start software, users can launch a Java application by clicking a link in a web page. The link points to a Java Network Launch Protocol (JNLP) file, which instructs Java Web Start software to download, cache, and run the application.

Java Web Start software provides Java developers and users with many deployment advantages:
  • With Java Web Start software, you can place a single Java application on a web server for deployment to a wide variety of platforms, including Windows, Linux, and Solaris.
  • Java Web Start software supports multiple, simultaneous versions of the Java platform. An application can request a specific version of the Java Runtime Environment (JRE) software without conflicting with the needs of other applications.
  • Users can create a desktop shortcut to launch a Java Web Start application outside a browser.
  • Java Web Start software takes advantage of the inherent security of the Java platform. By default, applications have restricted access to local disk and network resources.
  • Applications launched with Java Web Start software are cached locally for improved performance.
  • Updates to a Java Web Start application are automatically downloaded when the application is run standalone from the user's desktop.
Java Web Start software is installed as part of the JRE software. Users do not have to install Java Web Start software separately or perform additional tasks to use Java Web Start applications.

Developing a Java Web Start Application


Software designed by using component-based architecture can easily be developed and deployed as a Java Web Start application. Consider the example of a Java Web Start application with a Swing-based graphical user interface (GUI). With component-based design, the GUI can be built with smaller building blocks or components. The following general steps are used to create an application's GUI:
  • Create a MyTopJPanel class that is a subclass of JPanel. Lay out your application's GUI components in the constructor of the MyTopJPanel class.
  • Create a class called MyApplication that is a subclass of the JFrame class.
  • In the main method of the MyApplication class, instantiate the MyTopJPanel class and set it as the content pane of the JFrame.
The following sections explore these steps in greater detail by using the Dynamic Tree Demo application. If you are not familiar with Swing, see Creating a GUI with Swing to learn more about using Swing GUI components.

Note:  If you don't see the example running, you might need to enable the JavaScript interpreter in your browser so that the Deployment Toolkit script can function properly.

Creating the Top JPanel Class

Create a class that is a subclass of JPanel. This top JPanel acts as a container for all your other UI components. In the following example, the DynamicTreePanel class is the topmost JPanel. The constructor of the DynamicTreePanel class invokes other methods to create and lay out the UI controls properly.

public class DynamicTreePanel extends JPanel implements ActionListener {
    private int newNodeSuffix = 1;
    private static String ADD_COMMAND = "add";
    private static String REMOVE_COMMAND = "remove";
    private static String CLEAR_COMMAND = "clear";

    private DynamicTree treePanel;

    public DynamicTreePanel() {
        super(new BorderLayout());
   
        //Create the components.
        treePanel = new DynamicTree();
        populateTree(treePanel);

        JButton addButton = new JButton("Add");
        addButton.setActionCommand(ADD_COMMAND);
        addButton.addActionListener(this);
   
        JButton removeButton = new JButton("Remove");
        ....
   
        JButton clearButton = new JButton("Clear");
        ...
   
        //Lay everything out.
        treePanel.setPreferredSize(
            new Dimension(300, 150));
        add(treePanel, BorderLayout.CENTER);

        JPanel panel = new JPanel(new GridLayout(0,3));
        panel.add(addButton);
        panel.add(removeButton);
        panel.add(clearButton);
        add(panel, BorderLayout.SOUTH);
    }
    // ...
}

Creating the Application

For an application that has a Swing-based GUI, create a class that is a subclass of javax.swing.JFrame.

Instantiate your top JPanel class and set it as the content pane of the JFrame in the application's main method. The main method of the DynamicTreeApplication class invokes the createGUI method in the AWT Event Dispatcher thread.

package webstartComponentArch;

import javax.swing.JFrame;

public class DynamicTreeApplication extends JFrame {
    public static void main(String [] args) {
        DynamicTreeApplication app = new DynamicTreeApplication();
        app.createGUI();
    }

    private void createGUI() {
        //Create and set up the content pane.
        DynamicTreePanel newContentPane = new DynamicTreePanel();
        newContentPane.setOpaque(true);
        setContentPane(newContentPane);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }
}

Benefits of Separating Core Functionality From the Final Deployment Mechanism

Another way to create an application is to just remove the layer of abstraction (separate top JPanel) and lay out all the controls in the application's main method itself. The downside to creating the GUI directly in the application's main method is that it will be more difficult to deploy your functionality as an applet, if you choose to do so later.

In the Dynamic Tree Demo example, the core functionality is separated into the DynamicTreePanel class. It is now trivial to drop the DynamicTreePanel class into a JApplet and deploy it as an applet.

Hence, to preserve portability and keep deployment options open, follow component-based design as described in this topic.

Retrieving Resources


Use the getResource method to read resources from a JAR file. For example, the following code retrieves 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 the application's JAR file:

  • images/save.gif
  • images/cut.gif

Deploying a Java Web Start Application


To deploy your Java Web Start application, first compile the source code, package it as a JAR file, and sign the JAR file.

Java Web Start applications are launched by using the Java Network Launch Protocol (JNLP). Hence, you must create a JNLP file to deploy your application.

The Deployment Toolkit script contains useful JavaScript functions that can be used to deploy Java Web Start applications on a web page.

If you are unfamiliar with these deployment technologies, review the Deployment In-Depth lesson before proceeding.

Here are some step-by-step instructions to package and deploy your application. The Dynamic Tree Demo application is used to illustrate the deployment of Java Web Start applications. You might want to set up build scripts to execute some of the following steps.

Note:  If you don't see the example running, you might need to enable the JavaScript interpreter in your browser so that the Deployment Toolkit script can function properly.

1. Compile your application's Java code and make sure that all class files and resources such as images are in a separate directory.

In the Dynamic Tree Demo application, the compiled classes are placed in the build/classes/webstartComponentArch directory.

2. Create a text file that contains any JAR file manifest attributes that your applet needs.
For the DynamicTree Demo applet, create a file named mymanifest.txt in the build/classes directory, and add the Permissions, Codebase, and Application-Name attributes. The applet does not require access to the user's system resources, so use sandbox for the permissions. Use the domain from which you will load the sample for the code base, for example, myserver.com. Add the following attributes to the mymanifest.txt file.

Permissions: sandbox
Codebase: myserver.com
Application-Name: Dynamic Tree Demo

Other manifest attributes are available to restrict an applet to using only trusted code, and to provide security for applets that need to make calls between privileged Java code and sandbox Java code, or have JavaScript code that calls the applet. See the Enhancing Security with Manifest Attributes lesson to learn more about the manifest attributes that are available.

3. Create a JAR file containing your application's class files and resources. Include the manifest attributes in the mymanifest.txt file that you created in the previous step.
For example, the following command creates a JAR file with the class files in the build/classes/webstartComponentArch directory and the manifest file in the build/classes directory.

% cd build/classes
% jar cvfm  DynamicTreeDemo.jar  mymanifest.txt webstartComponentArch

4. Sign the JAR file for your applet and time stamp the signature. Use a valid, current code signing certificate issued by a trusted certificate authority to provide your users with assurance that it is safe to run the applet.

If you want to use a signed JNLP file for security, create the JNLP file as described in the next step and include it in the JAR file before the JAR file is signed. See Signed JNLP Files in the Java Platform, Standard Edition Deployment Guide for information.

5. Create a JNLP file that describes how your application should be launched.

Here is the JNLP file that is used to launch the Dynamic Tree Demo application. Permissions are not requested for this application so it runs in the security sandbox. The source for dynamictree_webstart.jnlp follows:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase=
"https://docs.oracle.com/javase/tutorialJWS/samples/deployment/webstart_ComponentArch_DynamicTreeDemo"
    href="dynamictree_webstart.jnlp">
    <information>
        <title>Dynamic Tree Demo</title>
        <vendor>Dynamic Team</vendor>
    </information>
    <resources>
        <!-- Application Resources -->
        <j2se version="1.7+"
              href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="DynamicTreeDemo.jar"
            main="true" />

    </resources>
    <application-desc
         name="Dynamic Tree Demo Application"
         main-class=
           "webstartComponentArch.DynamicTreeApplication"
         width="300"
         height="300">
     </application-desc>
     <update check="background"/>
</jnlp>          

Note: The codebase and href attributes are optional when deploying Java Web Start applications that will run on at least the Java SE 6 update 18 release or later. You must specify the codebase and href attributes when deploying Java Web Start applications that will run with previous releases of the Java Runtime Environment software.

6. Create the HTML page from which your application will be launched. Invoke Deployment Toolkit functions to deploy the Java Web Start application.
In the example, the Dynamic Tree Demo application is deployed in JavaWebStartAppPage.html.

<body>
    <!-- ... -->
    <script src=
      "https://www.java.com/js/deployJava.js"></script>
    <script>
        // using JavaScript to get location of JNLP
        // file relative to HTML page
        var dir = location.href.substring(0,
            location.href.lastIndexOf('/')+1);
        var url = dir + "dynamictree_webstart.jnlp";
        deployJava.createWebStartLaunchButton(url, '1.7.0');
    </script>
    <!-- ... -->
</body>

If you are not sure whether your end users will have the JavaScript interpreter enabled in their browsers, you can deploy the Java Web Start application directly by creating a link to the JNLP file as follows:

<a href="/absolute path to JNLP file/dynamictree_webstart.jnlp">Launch Notepad Application</a>

If you deploy the Java Web Start application with a direct link, you cannot take advantage of the additional checks that the Deployment Toolkit functions provide. See Deploying a Java Web Start Application in the Deployment In-Depth lesson for details.

7. Place the application's JAR file, JNLP file, and HTML page in the appropriate folders.

For this example, place DynamicTreeDemo.jar, dynamictree_webstart.jnlp, and JavaWebStartAppPage.html in the same directory on the local machine or a web server. A web server is preferred. To run from the local machine, you must add your application to the exception site list, which is managed from the Security tab of the Java Control Panel.

8. Open the application's HTML page in a browser to view the application. Agree to run the application when prompted. Check the Java Console log for error and debugging messages.
Download source code for the Dynamic Tree Demo example to experiment further.

Setting Up a Web Server


You might need to configure your web server to handle Java Network Launch Protocol (JNLP) files. If the web server is not set up properly, the Java Web Start application will not launch when you click on the link to the JNLP file.

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

The specific steps to set up the JNLP MIME type will vary depending on the web server. As an example, to configure an Apache web server, you should add the following line to the mime.types file.

application/x-java-jnlp-file JNLP

For other web servers, check the documentation for instructions on setting MIME types.

Displaying a Customized Loading Progress Indicator


A Java Web Start application can display a customized loading progress indicator that shows the progress of download of the application's resources.

Consider the Weather application and the CustomProgress class to understand how to implement a customized loading progress indicator for a Java Web Start application. For the purpose of demonstrating a large and prolonged download, this Java Web Start application's JAR file has been artificially inflated and the customprogress_webstart.jnlp file specifies additional JAR files as resources.

Developing a Customized Loading Progress Indicator

To develop a customized loading progress indicator for your Java Web Start application, create a class that implements the DownloadServiceListener interface.

The constructor of the loading progress indicator class should not have any parameters.

import javax.jnlp.DownloadServiceListener;
import java.awt.Container;
import java.applet.AppletStub;
import netscape.javascript.*;
// ...
public class CustomProgress
        implements DownloadServiceListener {
    JFrame frame = null;
    JProgressBar progressBar = null;
    boolean uiCreated = false;

    public CustomProgress() {
    }
...
}

The following code snippet shows how to build the UI for the loading progress indicator:

private void create() {
    JPanel top = createComponents();
    frame = new JFrame(); // top level custom progress
                          // indicator UI
    frame.getContentPane().add(top,
                               BorderLayout.CENTER);
    frame.setBounds(300,300,400,300);
    frame.pack();
    updateProgressUI(0);
}

private JPanel createComponents() {
    JPanel top = new JPanel();
    top.setBackground(Color.WHITE);
    top.setLayout(new BorderLayout(20, 20));

    String lblText =
        "<html><font color=green size=+2" +
        ">JDK Documentation</font><br/> " +
        "The one-stop shop for Java enlightenment! <br/></html>";
    JLabel lbl = new JLabel(lblText);
    top.add(lbl, BorderLayout.NORTH);
    ...
    progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    top.add(progressBar, BorderLayout.SOUTH);

    return top;
}

Create and update the loading progress indicator in the following methods based on the overallPercent argument. These methods are invoked regularly by the Java Web Start software to communicate the progress of the application's download. Java Web Start software will always send a message when download and validation of resources is 100% complete.

public void progress(URL url, String version, long readSoFar,
                     long total, int overallPercent) {    
    updateProgressUI(overallPercent);

}

public void upgradingArchive(java.net.URL url,
                  java.lang.String version,
                  int patchPercent,
                  int overallPercent) {
    updateProgressUI(overallPercent);
}

public void validating(java.net.URL url,
            java.lang.String version,
            long entry,
            long total,
            int overallPercent) {
    updateProgressUI(overallPercent);
}

private void updateProgressUI(int overallPercent) {
    if (overallPercent > 0 && overallPercent < 99) {
        if (!uiCreated) {
            uiCreated = true;
            // create custom progress indicator's
            // UI only if there is more work to do,
            // meaning overallPercent > 0 and
            // < 100 this prevents flashing when
            // RIA is loaded from cache
            create();
        }
        progressBar.setValue(overallPercent);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.setVisible(true);
            }
        });
    } else {
        // hide frame when overallPercent is
        // above 99
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.setVisible(false);
                frame.dispose();
            }
        });
    }
}

Compile the loading progress indicator class and build a JAR file with all the resources needed to display the loading progress indicator. Include the <your JRE directory>/lib/javaws.jar file in your classpath to enable compilation.

The loading progress indicator class is now ready for use. The next step is to specify this loading progress indicator JAR file as your Java Web Start application's progress indicator.

Specifying a Customized Loading Progress Indicator for a Java Web Start Application

To specify a customized loading progress indicator for a Java Web Start application, include the following information in the application's JNLP file:
  • jar tag with the download="progress" attribute
  • progress-class attribute with the fully qualified name of the customized loading progress class.
The following code snippet from the customprogress_webstart.jnlp file displays the usage of the download="progress" and progress-class attributes.

<jnlp spec="1.0+" codebase=
  "https://docs.oracle.com/javase/tutorialJWS/samples/deployment"
   href="customprogress_webstartJWSProject/customprogress_webstart.jnlp">
  <!-- ... -->
  <resources>
    <j2se version="1.7+"/>
    <jar href=
      "webstart_AppWithCustomProgressIndicator/webstart_AppWithCustomProgressIndicator.jar" />
    <jar href=
      "webstart_CustomProgressIndicator/webstart_CustomProgressIndicator.jar"
         download="progress" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/IconDemo.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/SplitPaneDemo.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/SplitPaneDemo2.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/TextBatchPrintingDemo.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/ToolBarDemo.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/ToolBarDemo2.jar" />
    <jar href=
      "webstart_AppWithCustomProgressIndicator/lib/SwingSet2.jar" />
  </resources>
  <application-desc
      main-class="customprogressindicatordemo.Main"
      progress-class="customprogressindicator.CustomProgress"
  />
  <!-- ... -->
</jnlp>

Deploy the Java Web Start application in a web page. Open JavaWebStartAppPage.html in a web browser to view the customized loading progress indicator for the Weather application.

Note:  To view the example properly, you need to install at least the Java SE Development Kit (JDK) 6 update 18 release.

Note: If you have viewed this Java Web Start application before, clear your cache by using the Java Control Panel before viewing the application again. You will not be able to see a progress indicator for a previously cached application.

Note:  If you don't see the example running, you might need to enable the JavaScript interpreter in your browser so that the Deployment Toolkit script can function properly.

Running a Java Web Start Application


Users can run Java Web Start applications in the following ways:
  • Running a Java Web Start Application From a Browser
  • Running a Java Web Start Application From the Java Cache Viewer
  • Running a Java Web Start Application From the Desktop
Note: To run applications deployed with Java Web Start technology, you must have a compatible version of the Java Runtime Environment (JRE) software. The complete Java Java Development Kit (JDK) is not required.

1. Running a Java Web Start Application From a Browser

You can run a Java Web Start application from a browser by clicking a link to the application's JNLP file. The following text is an example of a link to a JNLP file.

<a href="/some/path/Notepad.jnlp">Launch Notepad Application</a>

Java Web Start software loads and runs the application based on instructions in the JNLP file.

2. Running a Java Web Start Application From the Java Cache Viewer

If you are using at least Java Platform, Standard Edition 6 or later, you can run a Java Web Start application through the Java Cache Viewer.

When Java Web Start software first loads an application, information from the application's JNLP file is stored in the local Java Cache Viewer. To launch the application again, you do not need to return to the web page where you first launched it; you can launch it from the Java Cache Viewer.

To open the Java Cache Viewer:
  1. Open the Control Panel.
  2. Double click on the Java icon. The Java Control Panel opens.
  3. Select the General tab.
  4. Click View. The Java Cache Viewer opens.
The application is listed on the Java Cache Viewer screen.

Developing and Deploying Java Web Start Applications
Java Cache Viewer application
To run the application, select it and click the Run button, The Run button, or double click the application. The application starts just as it did from the web page.

3. Running a Java Web Start Application From the Desktop

You can add a desktop shortcut to a Java Web Start application. Select the application in the Java Cache Viewer. Right-click and select Install Shortcuts or click the Install button, The Install button.

A shortcut is added to the desktop.
Developing and Deploying Java Web Start Applications

You can then launch the Java Web Start application just as you would launch any native application.

Java Web Start and Security


This section describes the basics of security for applications deployed through Java Web Start and includes:

Applications launched with Java Web Start are, by default, run in a restricted environment, known as a sandbox. In this sandbox, Java Web Start:
  • Protects users against malicious code that could affect local files
  • Protects enterprises against code that could attempt to access or destroy data on networks
Sandbox applications that are launched by Java Web Start remain in this sandbox, meaning they cannot access local files or the network. See Security in Rich Internet Applications for information.

Dynamic Downloading of HTTPS Certificates


Java Web Start dynamically imports certificates as browsers typically do. To do this, Java Web Start sets its own https handler, using the java.protocol.handler.pkgs system properties, to initialize defaults for the SSLSocketFactory and HostnameVerifier. It sets the defaults with the methods HttpsURLConnection.setDefaultSSLSocketFactory and HttpsURLConnection.setDefaultHostnameVerifier.

If your application uses these two methods, ensure that they are invoked after the Java Web Start initializes the https handler, otherwise your custom handler will be replaced by the Java Web Start default handler.

You can ensure that your own customized SSLSocketFactory and HostnameVerifiter are used by doing one of the following:
  • Install your own https handler, to replace the Java Web Start https handler.
  • In your application, invoke HttpsURLConnection.setDefaultSSLSocketFactory or HttpsURLConnection.setDefaultHostnameVerifier only after the first https URL object is created, which executes the Java Web Start https handler initialization code first.

Common Java Web Start Problems


This section covers some common problems that you might encounter when developing and deploying Java Web Start applications. After each problem is a list of possible reasons and solutions.

Problem: My browser shows the Java Network Launch Protocol (JNLP) file for my application as plain text.

Most likely, your web server is not aware of the proper MIME type for JNLP files.

Furthermore, if you are using a proxy server, ensure that the update versions of the files are returned, by updating the time stamp of the resources on the web server such that the proxies will update their caches.

Problem: When I try to launch my JNLP file, I get the following error:

MissingFieldException[ The following required field is missing from the launch
  file: (<application-desc>|<applet-desc>|<installer-desc>|<component-desc>)]
        at com.sun.javaws.jnl.XMLFormat.parse(Unknown Source)
        at com.sun.javaws.jnl.LaunchDescFactory.buildDescriptor(Unknown Source)
        at com.sun.javaws.jnl.LaunchDescFactory.buildDescriptor(Unknown Source)
        at com.sun.javaws.jnl.LaunchDescFactory.buildDescriptor(Unknown Source)
        at com.sun.javaws.Main.launchApp(Unknown Source)
        at com.sun.javaws.Main.continueInSecureThread(Unknown Source)
        at com.sun.javaws.Main.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Often this error occurs when your XML is malformed. You can stare at the code until you figure it out but it is easier to run an XML syntax checker over the file. (NetBeans IDE and jEdit both provide XML syntax checkers.)

However, this error can occur in a other situations and the above was caused by the following line in an otherwise well-formed XML file:

<description kind="short">Demonstrates choosing the drop location in the target <code>TransferHandler</code></description>

The error was caused by the illegal embedded code tags.

Answers to Questions and Exercises: Java Web Start


Questions

1. Question: In a link that is to run a Java Web Start application, which file is specified as the a tag's href attribute?
Answer: You use the application's JNLP file name as the value of the href attribute. When a user clicks the link to the JNLP file, Java Web Start loads the application specified by that JNLP file.

2. Question: Which MIME type must a Web server recognize in order for it to host Java Web Start applications?
Answer: You must configure the Web server so that files with the .jnlp extension are set to the application/x-java-jnlp-file MIME type.

3. Question: In an application's JNLP file, which two elements must be specified within the resources element?
Answer: The resources element must contain:
  • The j2se element, which specifies the Java platform on which to run the application.
  • The jar element, which specifies the JAR file for the application.
4. Question: Which interface provides the ability to an application to control how its own resources are cached?
  1. BasicService
  2. DownloadService
  3. PersistenceService
  4. ExtendedService
Answer: B. The DownloadService interface provides the ability to an application to control how its own resources are cached.

5. Question: True or False: Java Web Start applications run in a secure sandbox by default.

Answer: True.

6. Question: True or False: If a Java Web Start application is running in a secure sandbox, JAR files for the application can reside on different servers.
Answer: False. All JAR files for the application must reside on the same server.

7. Question: For a Java Web Start application to support operations outside of the secure sandbox, what must you do?
Answer: You must include the security element in your .jnlp file and specify all-permissions to enable your application to work outside of the sandbox.

Exercises


1. Exercise: Write the XML code you would add to a JNLP file in order to request that the application have complete access to the client system.
Answer:

<security>
   <all-permissions/>
</security>
2. Exercise: For a Java Web Start application, you have two icons, one.gif and two.gif, in the images directory in a JAR file. Write the application code you would use to access these images.
Answer:

// Get current classloader
ClassLoader cl = this.getClass().getClassLoader();
// Create icons
Icon firstIcon  = new ImageIcon(cl.getResource("images/one.gif"));
Icon secondIcon   = new ImageIcon(cl.getResource("images/two.gif"));

«« Previous
Next »»