Java tip: Deploying JavaFX apps to multiple environments

Get around the 'gotchas' of JavaFX deployment

JavaFX 2.0.2 and successor SDKs let you deploy JavaFX applications in multiple environments including as a standalone app, via Java Web Start, or embedded in a web page. Jeff Friesen follows up his recent introduction to JavaFX 2.0 with this short tip on deploying JavaFX applications.

If you've read my three-part introduction to JavaFX 2.0, then you will be familiar with JPadFX, the Swing-based notepad that I used as a refactoring example for that series. Even if you're not familiar with JPadFX, you should be able to follow this tip. We'll concentrate on deploying the application, so you won't need to know much about its internals. Do go ahead and download JPadFX now.

Prepare JPadFX for deployment

Source files for the JPadFX app are JPad.java, About.java, Alert.java, AreYouSure.java, and the resource file icon.png. Once you have extracted these files to your current directory, execute the following command to compile the app on Windows:

javac -cp "C:\Program Files\Oracle\JavaFX 2.0
SDK\rt\lib\jfxrt.jar";. -d out JPadFX.java

I assume that you have installed the JavaFX 2.0.2 SDK to C:\Program Files\Oracle\JavaFX 2.0 SDK. Also, -d out stores the resulting class files in a subdirectory named out.

Deploying JPadFX as a standalone JavaFX application

JavaFX 2.0.2 provides a command-line tool, javafxpackager, that makes application deployment almost a snap. On my Windows XP platform, javafxpackager is installed in the C:\Program Files\Oracle\JavaFX 2.0 SDK\bin directory.

Once you have compiled JPadFX's source files, use javafxpackager to package the class files and JavaFX Launcher (a small set of classes that finds the installed JavaFX runtime and invokes the main application class via the runtime) into a JAR file as follows:

Listing 1. Package JPadFX with javafxpackager

javafxpackager -createjar -appclass JPadFX -srcdir out -outdir out -outfile
jpadfx.jar -v

Note the options specified in Listing 1:

  • -createjar tells javafxpackager to create a JAR file.
  • -appclass identifies JPadFX as the main class for the JAR manifest and JavaFX Launcher.
  • -srcdir identifies out as the directory containing the class files.
  • -outdir identifies out as the directory in which to create the JAR file.
  • -outfile identifies jpadfx.jar as the name of the JAR file.
  • -v specifies verbose output, which can be useful should an error message be displayed.

If the previous command succeeds, you will need to introduce icon.png to jpadfx.jar. A simple way to do this is to use the JDK's jar tool. Assuming that the current directory contains icon.png and the out subdirectory, execute the following command to store icon.png in jpadfx.jar:

jar uf
out\jpadfx.jar icon.png

At this point, you might want to try running JPadFX in standalone mode in order to test the JAR file's veracity. First, switch to the out directory (which contains jpadfx.jar) and execute a command similar to the following:

java -cp "C:\Program Files\Oracle\JavaFX 2.0
SDK\rt\lib\jfxrt.jar";. -jar jpadfx.jar

This command adds jfxrt.jar to java's classpath, which contains JavaFX class files that the JVM needs to load at runtime.

Deploying JPadFX in a web page and via Java Web Start

You can now use javafxpackager to create an HTML page and a deployment descriptor (JNLP) file to handle the scenarios of embedding the JavaFX application into a web page or running it via Java Web Start. The command in Listing 2 assumes that you are using the same directory used in Listing 1:

Listing 2. Create an HTML page and deployment descriptor for JPadFX via javafxpackager

javafxpackager -deploy -outdir out -outfile JPadFX -width 400 -height
400 -srcdir out -srcfiles jpadfx.jar
               -appclass JPadFX -name "JPad FX" -title "JPadFX Equivalent of
JPad" -vendor "Jeff Friesen" -v

The following options are specified:

  • -deploy tells javafxpackager to create the deployment HTML and JNLP files.
  • -outdir identifies out as the directory in which to store the HTML and JNLP files.
  • -outfile identifies JPadFX as the name of the HTML and JNLP files. This option must be present; otherwise, javafxpackager throws an exception.
  • -width identifies the width of the web page space devoted to the embedded application. I've chosen 400 for the width.
  • -height identifies the height of the web page space devoted to the embedded application. I've chosen 400 for the height.
  • -srcdir identifies out as the directory containing the JAR file.
  • -srcfiles identifies jpadfx.jar as the JAR file.
  • -appclass identifies JPadFX as the main application class to be executed.
  • -name identifies JPad FX as the name of the application. This information appears as the heading on the HTML page. If the name has a space, enclose the string in quotation marks.
  • -title identifies JPadFX Equivalent of JPad as the application's title. This information is stored in the JNLP file.
  • -vendor identifies Jeff Friesen as the application's vendor. This information is stored in the JNLP file.
  • -v specifies verbose output, which can be useful should an error message be displayed.

At this point, your out directory should contain JPadFX.jnlp and JPadFX.html along with jpadfx.jar.

Because JPadFX accesses the local filesystem, you must sign jpadfx.jar; otherwise, an exception will be thrown when you try to perform a file-oriented task, when the application is embedded in a web page or run from Java Web Start. Assuming that you haven't purchased a certificate, you also need to create a self-signed certificate. Use the JDK's keytool program to perform both tasks, as follows:

keytool -genkey -keystore jpadfx.ks -alias jpadfx
keytool -selfcert -alias jpadfx -keystore jpadfx.ks

This command creates a new key in a new keystore named jpadfx.ks, which is created in the current directory. For convenience, I've specified jpadfx as the alias. You will be prompted for information regarding the new key, such as password, name, and so on. Simply follow the prompts.

The second command creates a self-signed test certificate. You'll be prompted to enter a password and then the certificate will be created.

Unfortunately, it is problematic to use javafxpackager to sign the previously created jpadfx.jar file with the test certificate. For this reason, I use the jarsigner command directly, as demonstrated below:

jarsigner -keystore jpadfx.ks out\jpadfx.jar jpadfx

Double-click JPadFX.jnlp from a file manager program to run JPadFX via Java Web Start. Similarly, double-click JPadFX.html to load this HTML file in a browser and run the application in that context (see Figure 1). In either scenario, you must grant permission to give the application unrestricted access.

Figure 1. A screenshot of the JPadFX app embedded in a Mozilla Firefox web browser (click to enlarge)

In conclusion

You can compile and deploy JPadFX under JavaFX 2.0.2, JavaFX 2.0.3, and JavaFX 2.1. For each version, javafxpackager makes it easy to deploy this JavaFX app to multiple environments. JavaFX 2.0.2's version of this tool is somewhat problematic, resulting in your having to explicitly use jarsigner to sign jpadfx.jar with a test certificate.

For each of versions 2.0.2, 2.0.3, or 2.1, JPadFX exhibits a serious problem when run on a 64-bit Windows platform. Selecting Open, Save, or Save As from the File menu results in the following error messages:

Error: 80070057 in SHCreateItemFromParsingName((PCWSTR)
folder, NULL,
                                               IID_IShellItem,
                                               (void **) &pItem)
COM Error: 80070057 The parameter is incorrect.
Error: 80004005 in pOpenDialog->GetResults(&pFiles)
COM Error: 80004005 Unspecified error
java.lang.NullPointerException

As pointed out by a poster in the Oracle Discussion Forums, these messages appear to be related to a low-level Microsoft COM error in a native library accessed by the javafx.stage.DirectoryChooser and javafx.stage.FileChooser Windows implementations.

Jeff Friesen is a freelance tutor and software developer with an emphasis on Java and Android. In addition to writing Java and Android books for Apress, Jeff has written numerous articles on Java and other technologies for JavaWorld, informIT, Java.net, and DevSource. Jeff can be contacted via his website at TutorTutor.ca.

This story, "Java tip: Deploying JavaFX apps to multiple environments" was originally published by JavaWorld.

Related:

Copyright © 2012 IDG Communications, Inc.