This topic explains how to deploy Java and JavaFX applications in the browser using the Deployment Toolkit, dtjava.js
. An API overview, information about the callback methods, and typical examples of use are provided.
Use the Deployment Toolkit library to embed a Java or JavaFX application in a web page or launch it from a browser. The Deployment Toolkit provides a JavaScript API to simplify web deployment of applications and improve the end user experience when starting the application.
In addition to providing functionality to add HTML tags needed to insert Java or JavaFX applications into the web page, the Deployment Toolkit also provides the following actions:
Detects if the user's environment is supported
Offers to install the JRE, if needed
Provides visual feedback to the user while the application is loaded
Reports unexpected errors to the user
Provides other helper APIs to the developer, which can be used to simplify deployment and integration with the web page
To use the Deployment Toolkit, import the Deployment Toolkit JavaScript file from the shared location at http://java.com/js/dtjava.js
.
This way your application always uses the latest recommended way to integrate into a web page. If you cannot use the shared location, you can include the necessary files with your application by using the includeDT
option in the <fx:deploy> Ant task.
Note that for the majority of simple use cases, the code needed for deployment is generated by the Java packaging tools (see Section 5.3.1, "Java Packaging Tools.") You can use callbacks to tune the default behavior further. If you need more flexibility, you can use the Deployment Toolkit APIs directly.
This topic contains the following sections:
The Deployment Toolkit API provides the following important methods:
dtjava.embed(app, platform, callbacks)
Embeds the application into the browser based on a given application descriptor. If JRE installation is required, by default the Deployment Toolkit prompts the user to install the JRE or redirects to the page where the installer can be downloaded.
dtjava.launch(app, platform, callbacks)
Launches applications that are deployed outside of the browser, based on a given application descriptor. If JRE installation is required, then by default the Deployment Toolkit performs the following actions:
Attempts to start the JRE installer.
If automated installation of the Runtime is not possible, presents a popup request for the user to install manually.
dtjava.install(platform, callbacks)
Initiates installation of required components according to platform requirements.
dtjava.validate(platform)
Validates that the user's environment satisfies platform requirements, for example, verifies that the required version of the JRE is available. Returns PlatformMismatchEvent
describing problems, if any.
dtjava.hideSplash(id)
Hides the HTML splash screen for an application with a given ID. If the splash screen does not exist, this method has no effect. For JavaFX applications, this method is called automatically after the application is ready.
See the following sections for more information about arguments taken by these methods.
The application launch descriptor is an instance of the dtjava.App
object. The launch descriptor contains all of the details describing what needs to be launched. The dtjava.App
constructor takes the following parameters:
dtjava.App(url, {attribute_map});
The first parameter is the required url
attribute, which contains a URL or a relative link to the JNLP file. The second parameter is a subset of the attributes that are described in the following list:
id
Identifier of the application. The identifier is expected to be unique on the web page. If the identifier is null, then an identifier is autogenerated. Later, the identifier can be used to get the handle of the application in JavaScript code.
jnlp_content
(optional) Content of the JNLP file in BASE64 encoding.
params
The set of named parameters to pass to an application, if any. This attribute takes the following form:
params: {
variable: '
value' }
width
and height
Dimensions used to reserve space for an embedded application. The values can be absolute in pixels, or relative, for example, 50 or 50%.
placeholder
Reference to a DOM node, or an identifier of a DOM node, in which to embed an application.
toolkit
Identifies the UI toolkit used. Use fx
for JavaFX applications, use swing
for Swing applications. If no value is specified, the parameter defaults to fx
.
Note: The |
Example 17-1 shows an example of application launch descriptor code for an application that runs in the browser.
Platform requirements for an application to launch are defined by the dtjava.Platform
object. The following attributes are supported:
javafx
The minimum JavaFX version needed. Default is null
.
jvm
Minimum version of the JRe needed. The default is 1.6+.
jvmargs
List of requested JVM arguments. The default is null
.
Version strings are treated according to the following rules:
The null version string is treated as if there is no requirement to have it installed. Validation passes whether this component is installed or not.
The version pattern strings are of the form #[.#[.#[_#]]][+|*]
, which includes strings such as "1.7"
, "2.2*"
, and "1.7.0_25+"
.
An asterisk (*) means any version within this family, where family is defined by a prefix.
A plus sign (+) means any version greater or equal to the specified version.
If the version pattern does not include all four version components but does not end with an asterisk or plus sign, it will be treated as if it ended with an asterisk.
To clarify the differences, consider the following examples:
"1.6.0*"
matches 1.6.0_25 but not 1.7.0_01, whereas "1.6.0+"
or "1.*"
matches both.
"2.1"
is equivalent to "2.1*"
,and matches any version number beginning with "2.1".
Both asterisk and plus sign patterns match any installed version of the component. However, if the component is not installed, then validation fails.
Example 17-2 shows a dtjava.Platform
object:
Example 17-2 Example of a dtjava.Platform Object
var platform = new dtjava.Platform({ javafx: "2.2+", jvmargs: "-Dapp.property= ? -Xmx1024m" });
If platform requirements are not met, then dtjava.PlatformMismatchEvent
is returned, either as a return value from the validate()
method or passed to the onDeployError
callback. This object provides the following helper methods to identify root causes:
javafxStatus()
Returns ok
if the error was not due to a missing JavaFX Runtime. Otherwise, this method returns one of the following error codes characterizing the problem:
none
No JavaFX runtime is detected on the system.
old
A version of JavaFX Runtime is detected, but it does not match the platform requirements.
disabled
A matching version of JavaFX Runtime is detected, but it is disabled.
unsupported
JavaFX is not supported on this platform.
jreStatus()
Returns ok
if the error was not due to a missing JRE. Otherwise, this method returns one of the following error codes characterizing the problem:
none
No JRE was detected on the system.
old
A version of the JRE is detected, but it does not match the platform requirements.
oldplugin
A matching JRE was found, but it is configured to use a deprecated Java plug-in.
canAutoInstall()
Returns true
if the installation of missing components can be triggered automatically or if there are no missing components.
isRelaunchNeeded()
Returns true
if a browser must be restarted before the application can be loaded. This often is true in conjunction with the need to perform an installation.
isUnsupportedBrowser()
Returns true
if the current browser is not supported, for example, when the browser is out of date.
isUnsupportedPlatform()
Returns true
if this platform does not satisfy the supported platform requirements. For example, a JavaFX application attempts to launch on Solaris, which is not supported.
javafxInstallerURL (locale)
Returns the URL of a page to download and install the required version of the JRE manually. If a matching JRE is already installed or not supported, then the return value is null
.
jreInstallerURL (locale)
Returns the URL of a page to visit to install the required version of Java. If a matching JRE is already installed or not supported, then the return value is null
.
The Deployment Toolkit provides a set of hooks that can be used to customize startup behavior. To use the hook, the developer must provide a callback function. The following hooks are supported:
onDeployError: function(app, mismatchEvent)
Called when platform requirements are not met.
onInstallFinished: function(placeholder, component, status, relaunchNeeded)
Called after the installation of a required component is completed, unless installation was started manually.
onInstallNeeded: function(app, platform, cb, isAutoinstall, needRelaunch, launchFunc)
Called if embedding or launching an application needs additional components to be installed.
onInstallStarted - function(placeholder, component, isAuto, restartNeeded)
Called before installation of the required component is triggered.
The following hooks are specific to embedded applications:
onGetNoPluginMessage function(app)
Called to get content shown in the application area if the Java Plug-in is not installed and none of the callbacks have helped.
onGetSplash: function(app)
For embedded applications, called to get the content of the splash screen.
onJavascriptReady: function(id)
Called after the application is ready to accept JavaScript calls.
onRuntimeError: function(id)
Called if the application failed to launch.
This handler can be utilized to customize error handling behavior, such as showing messages in the user's language. See the example in Section 17.3.8, "Create a Handler for an Unsupported Platform" for an example of the onDeployError
handler.
A callback function is called if the application cannot be deployed because the current platform does not match the given platform requirements. It is also called if a request to install missing components cannot be completed due to platform incompatibility.
Function signature:
onDeployError : function(app, mismatchEvent)
The problem can be a fatal error or a transient issue, such as a required relaunch. Further details can be extracted from the mismatchEvent
that is provided. Here are some typical combinations:
The browser is not supported by Java.
mismatchEvent.isUnsupportedBrowser()
returns true
The browser must be restarted before the application can be launched.
mismatchEvent.isRelaunchNeeded()
returns true
JRE-specific codes:
JRE is not supported on this platform.
mismatchEvent.jreStatus() == "unsupported"
JRE is not detected and must be installed.
mismatchEvent.jreStatus() == "none"
The installed version of JRE does not match application requirements.
mimatchEvent.jreStatus() == "old"
A matching JRE is detected, but a deprecated Java Plug-in is used.
mimatchEvent.jreStatus() == "oldplugin"
JavaFX-specific codes:
JavaFX is not supported on this platform.
mismatchEvent.javafxStatus() == "unsupported"
JavaFX Runtime is missing and must be installed manually.
mismatchEvent.javafxStatus() == "none"
The installed version of JavaFX Runtime does not match application requirements.
mismatchEvent.javafxStatus() == "old"
JavaFX Runtime is installed but is disabled.
mismatchEvent.javafxStatus() == "disabled"
The default error handler handles both application launch errors and embedded content.
This handler is called to get content to be shown in the application area if the Java Plug-in is not installed and none of the callbacks helped to resolve the situation.
Function signature:
onGetNoPluginMessag : function(app)
This handler gets the content of the splash screen when the application is embedded in a browser.
Function signature:
onGetSplash: function(app)
Gets the application launch descriptor as input. If null is returned, then the splash screen is disabled. A non-null return value is expected to be a HTML code to be added into the splash overlay. Note that the splash overlay does not enforce any specific size. You must ensure that the custom splash image is sized to fit the area in which the application will run.
For examples of customizing the splash screen, see Section 17.3.7, "Add a Custom HTML Splash Screen" and Section 17.3.6, "Disable the HTML Splash Screen."
Note: Automatically hiding the splash screen is only supported by JavaFX applications. If you are deploying a Swing applet, then the application must call |
This handler is called after the installation of a required component is completed. This method is not called if the installation is performed in manual mode.
Function signature:
onInstallFinished: function(placeholder, component, status, relaunchNeeded)
Parameters:
placeholder
: A DOM element that was passed to onInstallStarted
to insert visual feedback.
component
: String "jre
" or "javafx"
status
: String that categorizes the status of the installation, for example, "success", "error:generic", "error:download" or "error:canceled"
.
relaunchNeeded
: Boolean value to specify if a browser restart is required to complete the installation.
This handler is called if the embedding or launching application needs additional components to be installed. This callback is responsible for handling situations such as reporting to the user the need to install something, initiating installation using install()
, and hiding the splash screen for embedded applications, if needed. After installation is complete, the callback implementation can retry the attempt to launch the application using the provided launch function.
This method is not called if the platform requirement could not be met, for example, if the platform is not supported or if installation is not possible.
The default handler provides a click-to-install solution for applications embedded in a browser and attempts to perform installation without additional questions for applications that have been started using launch().
If the handler is null, then it is treated as a no-op handler.
Function signature:
onInstallNeeded
: function(app, platform, cb, isAutoinstall, needRelaunch, launchFunc)
Parameters:
app
: Application launch descriptor. For embedded applications, app.placeholder
refers to the root of the embedded application area in the DOM tree, which is used for visual feedback.
platform
: Application platform requirements.
cb
: The set of callbacks to be used during the installation process.
isAutoinstall
: True, if the installation can be launched automatically.
needRestart
: True, if restarting the browser is required after installation is complete.
launchFunction
: Function to be executed to retry launching the application after the installation is finished.
This handler is called before the installation of the required component is triggered. For a manual installation scenario, it is called before the installation page is opened.
This hook can be used to provide visual feedback to the user during the installation. The placeholder points to the area that can be used for visualization. For embedded applications, this is the area into which the application will be embedded. If null, then the object called must find a place for display on its own.
In case of automatic launch of the installation, onInstallFinished
is called after installation is complete, successfully or not.
If the handler is null, then it is treated as no-op handler.
Function signature:
onInstallStarted: function(placeholder, component, isAuto, restartNeeded)
Parameters:
placeholder
: The DOM element to insert visual feedback into. If null, then the object called must add visual feedback to the document on its own, for example, embedding the application into a web page.
component
: String "Java", "JavaFX", or "Java bundle".
isAutoInstall
: True, if the installer is launched automatically.
restartNeeded
: Boolean value to specify if a browser restart is required.
This handler is called after the embedded application is ready to accept JavaScript calls.
Function signature:
onJavascriptReady
: function(id)
This handler is called if the embedded application fails to launch.
Function signature:
onRuntimeError
: function(id)
This section shows examples of deployment that use the Deployment Toolkit.
Note: Some of the Deployment Toolkit methods might not be fully operational if used before the web page body is loaded, because the Deployment Toolkit plug-ins cannot be instantiated. If you intend to use the Deployment Toolkit before the web page DOM tree is constructed, then |
To initiate deployment, use onload
handlers to add the application after the HTML content is loaded, for the following reasons:
The DOM tree must exist when the application content is inserted. The DOM tree is created after the HTML content page loads.
The Deployment Toolkit's detection code does not prevent loading of the HTML page.
The Deployment Toolkit avoids loading concurrently with other resources that are needed for the page.
Example 17-3 shows the default deployment scenario for applications embedded in a web page. The application is added to the web page in the deployIt()
function. This function is called after the page is loaded and its DOM tree is constructed. The position of the application in the DOM tree is determined by the value of the placeholder parameter. In this case, the application is inserted into a <div>
tag with id="place"
.
Adding the application to a web page after the main page is loaded helps to get a complete web page, including the embedded application, to load faster, because the application starts concurrently with loading other resources required by the web page.
Note that the value of the placeholder element can be a string or a JavaScript variable pointing to the container DOM node. If that node is detached from the document DOM tree, then the application is not initialized until the parent node is attached to the DOM tree.
Example 17-3 Insert the Application into the HTML Body with a Placeholder
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function deployIt() { dtjava.embed( { id: "myApp", url: "Fish.jnlp", width: 300, height: 200, placeholder: "place" }, { javafx: "2.2+" }, {} ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
The canonical form for the link to launch a Java Web Start application is shown in Example 17-4. Either relative or absolute links are acceptable.
Example 17-4 Canonical Link to Launch a Web Start Application
<a href="my.jnlp" onclick="dtjava.launch(new dtjava.App('my.jnlp')); return false;">Launch me!</a>
An alternative simplified syntax is shown in Example 17-5.
Example 17-5 Link to Launch a Web Start Application, Simplified
<a href="my.jnlp" onclick="dtjava.launch({url: 'my.jnlp'}); return false;">Launch me!</a>
A third form for simple applications is shown in the following example.
Example 17-6 Link to Launch a Web Start Application, Third Example
<a href="my.jnlp" onclick="dtjava.launch('my.jnlp'); return false;">Launch me!</a>
If JavaScript is disabled in the browser, the Deployment Toolkit does not work. In this case, the browser tries to use the href
attribute. If the JRE is installed, then the application launches. The return false;
statement ensures that the browser does not leave the current page if the launch is successful.
You can pass dynamic parameters to applications from a web page. For this you need to add a set of named parameters as the params
attribute of the application descriptor.
In Example 17-7, the embedded application gets two dynamic parameters from the web page. Note that the "zip" parameter is assigned with the value of the JavaScript variable.
Example 17-7 Pass Parameters to an Embedded Application
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function deployIt() { var zipcode = 95054; dtjava.embed( { id: "myApp", url: "Map.jnlp", width: 300, height: 200, placeholder: "place", params: { mode: "streetview", zip: zipcode } }, { javafx: "2.2+" }, {} ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
The same approach works for Java Web Start applications if the user has JRE 7u6 or later. Here is an example:
Example 17-8 Pass Parameters to a Web Start Application
<script> var zipcode = 95054; function launchApp() { dtjava.launch( { url: 'my.jnlp', params: { mode: "streetview", zip: zipcode } }, { javafx : '2.2+' }, {} ); return false; } </script> <a href="my.jnlp" onclick="launchApp(); return false;"> Launch me! </a>
To access parameters in the application code, use the getParameters()
method of the Application class, for example:
String zipcode = app.getParameters().getNamed("zip");
Use the second argument group of the dtjava.embed()
function to specify platform requirements for the application.
In Example 17-9, JRE 1.7 or later is specified in the jvm
parameter; JavaFX 2.2 or later is specified in the javafx
parameter; and the jvmargs
parameter indicates that the application should be executed in the Java Virtual Machine (JVM) with a 1 gigabyte heap size and given options.
Example 17-9 Specify Platform Requirements and Passing JVM Properties
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function deployIt() { dtjava.embed( { id: "my", url: "app.jnlp", width: 300, height: 200, placeholder: "place" }, { jvm: "1.7.0+", javafx: "2.2+", jvmargs: "-Dapp.property=somevalue -Xmx1024m" } ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
To access a Java or JavaFX application from JavaScript, you must get a reference to the JavaScript object representing the application. Specify an id
parameter in the first argument group of the dtjava.embed()
function, as shown in Example 17-3.
For example, if an id
parameter is set to my
, then a public method of the application can be accessed with the script shown in Example 17-10.
Example 17-10 Access an Application Method with an id Parameter
<script> var a = document.getElementById("my"); a.java_method(); </script>
Attempts to call application methods might not work until the application finishes the initialization phase. For a description of startup phases, see Section 4.2, "Application Startup Process, Experience, and Customization." To access an application while it is loading, use an onJavascriptReady
callback, as shown in Example 17-11.
Example 17-11 Access an Application Method While the Application Is Loading
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function callApp(id) { //it is safe to call now var a = document.getElementById(id); a.java_method(); } function deployIt() { dtjava.embed( { id: "my", url: "fxapp.jnlp", width: 300, height: 200, placeholder: "place" }, {}, { onJavascriptReady: callApp } ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
To disable the HTML splash screen for a JavaFX application, add an onGetSplash
handler that returns null:, as shown in Example 17-12. For information about application startup phases, see Section 4.2, "Application Startup Process, Experience, and Customization."
Example 17-12 Disable the HTML Splash Screen
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function deployIt() { dtjava.embed( { id: "my", url: "app.jnlp", width: 300, height: 200, placeholder: "place" }, { jvm: "1.7.0+", javafx: "2.2+", }, { onGetSplash: function(app) {return null;} } ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
If you are deploying a Swing applet, then the application must call dtjava.hideSplash()
explicitly to hide the splash screen.
Example 17-13 shows how to replace the default HTML splash screen with a green rectangle, defined in a JavaScript function.
Example 17-13 Replace the Splash Screen with a Custom One
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function getSplash(app) { //custom splash - green rectangle var p = document.createElement('div'); p.style.width = app.width; p.style.height = app.height; p.style.background="green"; return p; } function deployIt() { dtjava.embed( { id: "my", url: "app.jnlp", width: 300, height: 200, placeholder: "place" }, { jvm: "1.7.0+", javafx: "2.2+", }, { onGetSplash: getSplash } ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
Example 17-14 shows the use of JavaScript to handle an unsupported browser.
Example 17-14 Handle an Unsupported Browser with JavaScript
<head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function reportError(app, r) { //ovewrite behavior for unsupported browser var a = app.placeholder; if (a != null && r.isUnsupportedBrowser()) { var p = document.createElement('div'); p.id = "splash"; p.style.width = app.width; p.style.height = app.height; p.style.background="red"; p.appendChild( document.createTextNode("This browser is not supported.")); //clear embedded application placeholder while(a.hasChildNodes()) a.removeChild(a.firstChild); //show custom message a.appendChild(p); } else { //use default handlers otherwise var def = new dtjava.Callbacks(); return def.onDeployError(app, r); } } function deployIt() { dtjava.embed( { id: "my", url: "app.jnlp", width: 300, height: 200 }, { jvm: "1.7.0+", javafx: "2.2+", }, { onDeployError: reportError } ); } dtjava.addOnloadCallback(deployIt); </script> </head> <body> <div id="place"></div> </body>
Example 17-15 shows the use of JavaScript to replace the default text offering to install JavaFX. It is replaced with an offer to start the application only if the correct version of JavaFX is found on the user's system.
Example 17-15 Launch Only If JavaFX Is Installed
<html> <head> <script type="text/javascript" src="http://java.com/js/dtjava.js"></script> <script> function mayBeOfferLaunch() { var platform = new dtjava.Platform({'javafx' : '2.2+'}); //check if validate find any problems if (dtjava.validate(platform) == null) { var t = document.getElementById("text"); t.innerHTML = "<a href='my.jnlp' " + "onclick='dtjava.launch({url: 'my.jnlp'}); return false;'>" + "Launch me!</a>"; } } dtjava.addOnloadCallback(mayBeOfferLaunch); </script> </head> <body> <div id="text">To view this content you need <a href="http://javafx.com">to install JavaFX Runtime 2.2</a>.</div> </body> </html>