Deploying JavaFX Applications

Previous
Next

3 Application Execution Modes

This chapter explains different application execution modes.

One of the main features of the JavaFX application model is that you can write one application and easily deploy it several different ways. The user can experience the same application running on the desktop, in a browser, or starting from a link in a web page.

However, different execution modes are not completely equivalent. There are some important differences to keep in mind while developing the application.

This page contains the following topics:

3.1 Execution Modes

One of the main features of the JavaFX application model is that the applications you develop can be deployed in several different ways, as described in Table 3-1.

Table 3-1 JavaFX Execution Modes

Execution Mode Description

Run as a standalone program

The application package is available on a local drive. Users launch it using a Java launcher, such as java -jar MyApp.jar, or by double-clicking the application JAR file.

Launched from a remote server using Web Start

Users click a link in a web page to start the application from a remote web server. Once downloaded, a Web Start application can also be started from a desktop shortcut.

Embedded into a web page

JavaFX content is embedded in the web page and hosted on a remote web server.

Launched as a self-contained application

Application is installed on the local drive and runs as a standalone program using a private copy of Java and JavaFX runtimes. The application can be launched in the same way as other native applications for that operating system, for example using a desktop shortcut or menu entry.


Each execution environment has its own specific complications and usability issues. For example, for remote applications the loading phase can be very long because the application has to be loaded from the network. This is less of an issue for applications that run on a local drive.

3.2 Understanding Feature Differences

Figure 3-1 lists some of the features that behave differently in different environments. The following sections describe the figure in more detail.

Figure 3-1 Features of Deployment Types

See graphic description link
Description of "Figure 3-1 Features of Deployment Types"

3.2.1 Preloader Support

The preloader is a small JavaFX application that receives notifications about application loading and initialization progress. The preloader is used with all execution modes, but depending on the execution mode, the preloader implementation receives a different set of events and optimal behavior may be different.

For example, in self-contained application or standalone execution mode or when launched from a shortcut, the preloader will not get any loading progress events, because there is nothing to load. See Chapter 9, "Preloaders" for information about preloader implementation and differences in behavior.

3.2.2 Desktop Integration via Shortcut

Most of the operating systems allow applications to simplify subsequent launch and integrate with the user's desktop by creating a desktop shortcut or adding a link to the programs menu or dock.

Built-in support for desktop shortcuts is available for self-contained and web-deployed applications. There is no built-in support for standalone applications.

3.2.3 Built-In Proxy Support

Properly packaged JavaFX application have proxy settings initialized according to Java Runtime configuration settings. By default, this means proxy settings will be taken from the current browser if the application is embedded into a web page, or system proxy settings will be used. Proxy settings are initialized by default in all execution modes.

3.2.4 Run in Sandbox Unless Signed and Trusted

WebStart and embedded applications are, by default, run in a restricted environment, known as a sandbox. In this sandbox, Java Runtime does the following:

  • Protects users against malicious code that could affect local files.

  • Protects enterprises against code that could attempt to access or destroy data on networks.

Applications fall into three categories: signed and trusted, signed and not trusted, and unsigned. When running on a client (unless launched as a standalone application), un-trusted applications operate with maximum restrictions within a security sandbox that allows only a set of safe operations.

Un-trusted applications cannot perform the following operations:

  • They cannot access client resources such as the local filesystem, executable files, system clipboard, and printers.

  • They cannot connect to or retrieve resources from any third-party server (in other words, any server other than the server it originated from).

  • They cannot load native libraries.

  • They cannot change the SecurityManager.

  • They cannot create a ClassLoader.

  • They cannot read certain system properties. See System Properties for a list of forbidden system properties.

3.2.5 Auto-Updates

JavaFX applications that run from a web page or were earlier installed from the web automatically check for availability of updates to the application at the original location where the application is loaded. This happens every time an application starts, and, by default, the update runs in the background. The application is automatically updated if updates are detected.

For standalone and self-contained applications, you are responsible for handling updates.

3.2.6 Deployment Toolkit

The Deployment Toolkit performs two important functions:

  • It helps to simplify web deployment of JavaFX applications by managing updates.

  • It improves the end user experience while waiting for applications to start.

These two functions are intertwined, because the application startup phase is a critical component of user satisfaction. For example, the Deployment Toolkit verifies that the user has JavaFX Runtime installed, and if not, it will offer to install it before trying to run the application, without much effort on the user's part.

The Deployment Toolkit provides a JavaScript API and is only available for applications embedded in a web page or launched from a web page.

For more information about the Deployment Toolkit, see Chapter 7, "Deployment in the Browser."

3.2.7 Communicate to the Host Web Page

Applications embedded into a web page can communicate with it using JavaScript. To initiate communication, the application must get the web context from the JavaFX HostServices API. For any other execution environment, an attempt to get a reference to web context returns null.

See Chapter 8, "JavaFX and JavaScript" for information about using JavaScript to communicate with the browser.

3.2.8 Managing Platform Dependencies

To run JavaFX content, recent versions of the Java and JavaFX runtimes are required. Unless the application is self-contained, the Java and JavaFX runtimes need to be installed on the user's system.

For most users, JavaFX 2.2 and later will be installed as part of the Java Runtime and will be auto-updated to the latest secure version. If the user does not have the required version of the Java or JavaFX runtime he or she will be guided to install it.

However, there are situations in which system installations of the Java and JavaFX runtime and the auto-update functionality are not sufficient. For example:

  • The user does not have admin permissions to install the runtimes.

  • The user requires an older version of Java for other applications.

  • Users who need multiple system installations feel they are too complicated.

  • You want to set the exact version of Java and JavaFX to be used by your application.

  • Your distribution channel disallows dependencies on external frameworks

These issues are resolved if you choose to deploy your application as a self-contained application. The Java and JavaFX runtimes will be included in your application package, and users do not need to install them separately. The self-contained application package can be as simple as a .zip file distribution, or it can be wrapped into an installable package using technology that is native to the target operating system. See the topic Chapter 5, "Packaging Basics" for more details about self-contained application packages.

3.3 Coding Tips

The following small programming tips work well in all environments and simplify the development and deployment of applications.

3.3.1 Detecting Embedded Applications

When an application is run in embedded mode, it gets staged with predefined dimensions and cannot update them directly. Example 3-1 shows a very simple code snippet to detect if the application is embedded in the browser. The code can be used in either the main application or the preloader start method.

Example 3-1 Detect if the Application is Embedded in the Browser

public void start(Stage stage) {
    boolean isEmbedded = (stage.getWidth() > 0);
    ...
}

As an alternative, you can try to get a reference to the web context from the Application.getHostServices() method. It will be null unless the applications is embedded.

3.3.2 Accessing Application Parameters

JavaFX applications support both named and unnamed parameters that can be passed in a variety of ways:

  • They can be specified on the command line for a standalone launch.

  • They can be hardcoded in the application package (jar and deployment descriptor).

  • They can be passed from the HTML page in which the application is embedded.

To access parameters from a preloader or main application, use the getParameters() method. For example, the code in Example 3-2 gets a list of all named parameters and their values:

Example 3-2 Get a List of Named Deployment Parameters and Values

Map m = getParameters().getNamed();
int cnt = 0;
String labelText = "List of application parameters: \n";
for(String st: (Set<String>) m.keySet()) {
    labelText += "  ["+st+"] : ["+m.get(st)+"]\n";
    cnt++;
}

3.3.3 Consider the Use of Host Services

The Application.getHostServices() method provides access to execution-mode-specific services, including:

  • Access to information about the code base and the document base.

    For example, for embedded applications this is the URL of the application and URL of the host web page, respectively.

  • Access to the host web page using the JavaScript engine, only available to embedded applications.

  • Ability to open a web page in the browser.

Example 3-3 shows a few things you can do with getHostServices().

Example 3-3 Using getHostServices()

final HostServices services = getHostServices();
        
Button jsButton = new Button("Test Javascript");
jsButton.setOnAction(new EventHandler<ActionEvent>()  {
    public void handle(ActionEvent t) {
        JSObject js = services.getWebContext();
        js.eval("window.alert('Hello from JavaFX')");
    }            
});
 
Button openButton = new Button("Test openDocument()");
    openButton.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
        services.showDocument("http://javafx.com/");
    }
});

3.3.4 Loading Resources

Using the File API and explicit relative references to external data files or resources may not work when the application is loaded from the web.

The best way to refer to resources relative to your application is to use the getResource() method on one of the application classes, as shown in Example 3-4.

Example 3-4 Use the getResource() Method to Load Resources

scene.getStylesheets().
    add(this.getClass().getResource("my.css").toExternalForm());

As an alternative, consider using getCodeBase() or getDocumentBase() from the HostServices class to refer to resources relative to the application or the location where the application is used.

3.3.5 Resize-Friendly Applications

When an application is embedded into a web page, it cannot control stage dimensions. Dimensions you specify at packaging time are preferences only and can be overridden by the user, for example if the user has custom browser zoom settings. Moreover, the stage can be resized at runtime any time by the user.

To provide a good user experience, it is necessary to be prepared for arbitrary stage size. Otherwise, the application might be cropped, or there could be garbage painted in the unused area of the stage.

If your application uses layouts, then you do not need to do anything. Layouts take care of resizing for you. Otherwise, implement resizing logic and listen to stage dimension changes to update the application, as shown in the simplified code in Example 3-5.

Example 3-5 Using Listeners to Resize an Embedded Application

public class ResizeFriendlyApp extends Application implements 
        ChangeListener<Number> {
    private Stage stage;
    public void start(Stage stage) {
        //be resize friendly
        this.stage = stage;
        stage.widthProperty().addListener(this);
        stage.heightProperty().addListener(this);
 
        ...       
 
        //resize content
        resize(stage.getWidth(), stage.getHeight());
 
        stage.show(); 
    }
 
    private void resize(double width, double height) {
        //relayout the application to match given size
    }
 
    public void changed(ObservableValue<? extends Number> ov, 
            Number t, Number t1) {
        resize(stage.getWidth(), stage.getHeight());
    }
}
Previous
Next