[ Top page ] [ JavaFX index ]

Building JavaFX Standalone JAR Consisting of Multiple Jar Files

by Toru Takahashi

Introduction

This article is an English translation version of the 3rd day entry on JavaFX Advent Calendar 2012 in Japan.

I had a presentation about the mechanism of JavaFX application executable JAR(slide in Japanese/slide in English) at the Japan JavaFX Usergroup seminar on 30th November.

This presentation shows a simple executable JavaFX application program consisting of a single jar file.
After the presentation, I was asked a question of how to create JavaFX application jar consisting of multiple jar files.
At that time I didn't have the answer, so the answer is this article.

Review of Java Executable JAR

From Java SE 7 Update6, the JavaFX runtimes are contained in the Java SE's directory. But the JavaFX runtime jar file is separated from Java SE runtime jar files.
This means that the JavaFX runtime jar files need to be specified in class paths to execute a JavaFX application.

However, I can not specify the JavaFX runtime jar file in a java command -classpath option with -jar option for executable jar.
This restriction is documented at java command -jar option in Java SE 7 tool document, as below.

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.

To launch an executable jar with -jar option of java command, consisting jar files should be specified as a relative path in the executable jar's manifest file(MANIFEST.MF).

Review of JavaFX Standalone JAR

The JavaFX deployment provides a special bootstrap function for an executable jar to load JavaFX runtime jar files.
That bootstrap function is classes(com.javafx.main.Main, ...) inserted in a executable jar. In launch, bootstrap function searches the JavaFX runtimes and load, then start application.

This is the JavaFX standalone jar file.

To create a JavaFX standalone jar file, javafxpackager command and ant task are provided.

NetBeans IDE 7.2 has a JavaFX project to build a JavaFX standalone JAR file.

JavaFX Application Consisting of Multiple Jar Files

Real world applications are consisting of some libraries, that is jar file.

To demonstrate the JavaFX standalone JAR file consisting of multiple jar files, I create a tiny twitter viewer program using the twitter4j library.

Using NetBeans IDE

At first, create JavaFX project using NetBeans IDE.

Start NetBeans IDE 7.2 (or 7.3), from [File] menu > [New Project], select JavaFX Application.
Then add twitter4j library on project property. It's ok to add the twitter4j-core-3.0.1.jar file only for programming simple twitter functions.

Build the project to generated the following directries and files.

TwitterFX
  +-- build
  +-- dist
  |     +-- lib
  |     |     +-- twitter4j-core-3.0.1.jar
  |     +-- web-files
  |     |     +-- dtjava.js
  |     |     :
  |     |     +-- upgrade_javafx.png
  |     +-- TwitterFx.html
  |     +-- TwitterFx.jar
  |     +-- TwitterFx.jnlp

The twitter4j jar file is copied in the project's dist/lib directory.

Let's see the MANIFEST.MF in JavaFX application "TwitterFx.jar" file.

Manifest-Version: 1.0
implementation-vendor: torutk
JavaFX-Version: 2.2
implementation-title: TwitterFx
implementation-version: 1.0
JavaFX-Application-Class: twitterfx.TwitterFx
JavaFX-Class-Path: TwitterFx.jar lib/twitter4j-core-3.0.1.jar
Created-By: JavaFX Packager
Main-Class: com/javafx/main/Main
...

See the 'JavaFX-Class-Path' item, path to the twitter4j jar file is described.

Note that paths are as relative path.

Now launch this JavaFX standalone executable jar named "TwitterFx.jar" by double clicking on a file explorer (, or java command with -jar option).
The application is going to start.

Won't start with only JavaFX standalone jar file

For experiment, copy the "TwitterFx.jar" file only to another directory ( for example, C:\temp ).

C:\temp
  +-- TwitterFx.jar

Then start the "TwitterFx.jar" file copied.

An error has occurerd as follows.

To examine the error, start "TwitterFx.jar" on a java command with -jar option.

Caused by: java.lang.ClassNotFoundException: twitter4j.TwitterException
        at java.net.URLClassLoader$1.run(Unknown Source)

Above error message shows that the error is caused by missing twitter4j-core-3.0.1.jar.

To start successfully, it is necessary to copying all jar files described in 'JavaFX-Class-Path' section of MANIFEST.MF.
Files must be keeping relative path as following.

C:\temp
  +-- TwitterFx.jar
  +-- lib
        +-- twitter4j-core-3.0.1.jar

Let's start "TwitterFx.jar", from double clicking on a file explorer or java -jar on command prompt. It would be start successfully.

Using javafxpackager command

A JavaFX standalone JAR file can be generated by javafxpackager command included in JDK 7.

Below is a quotation from Deploying JavaFX Application document javafxpackager command -classpath option section.

To specify additional jar files is documented at javafxpackager command -classpath option section in Deploying JavaFX Application, as below.

-classpath <files>
  List of dependent JAR file names.

Create a JavaFX application JAR file using javafxpackager command.

c:\work\TwitterFx> javafxpackager -createjar 
 -appclass twitterfx.TwitterFx
 -srcdir build\classes -outdir dist -outfile TwitterFx-hand.jar
 -classpath lib\twitter4j-core-3.0.1.jar

Note: There is a NetBeans JavaFX application project directory, and source files are compiled in advance.

Let's see the 'JavaFX-Class-Path' in MANIFEST.MF in JavaFX standalone jar, "TwitterFx-hand.jar" file.

JavaFX-Class-Path: lib\twitter4j-core-3.0.1.jar

The described path is as same as the javafxpackager -classpath option value.

Absolute path is not acceptable in classpath option

I tried to specify absolute path of twitter4j-core-3.0.1.jar in javafxpackager -classpath option.

c:\work\TwitterFx> javafxpackager -createjar 
 -appclass twitterfx.TwitterFx
 -srcdir build\classes -outdir dist -outfile TwitterFx-hand.jar
 -classpath C:\java\lib\twitter4j\lib\twitter4j-core-3.0.1.jar

Then I launched the 'TwitterFx-hand.jar', an error has occurred.

java.io.IOException: The filename, directory name, or volume label syntax is incorrect
        at java.io.WinNTFileSystem.canonicalize0(Native Method)
        at java.io.Win32FileSystem.canonicalize(Win32FileSystem.java:414)
        at java.io.File.getCanonicalPath(File.java:589)
        at java.io.File.getCanonicalFile(File.java:614)
        at com.javafx.main.Main.fileToURL(Main.java:97)

Specifying classpath of multiple jar files with -classpath option

c:\work\TwitterFx> javafxpackager -createjar 
 -appclass twitterfx.TwitterFx
 -srcdir build\classes -outdir dist -outfile TwitterFx-hand.jar
 -classpath lib\twitter4j-async-3.0.1.jar;lib\twitter4j-core-3.0.1.jar

The javafxpackager command -classpath option accepts multiple paths.

Conclution

The JavaFX appliaction JAR mechanism uses a MANIFEST.MF included in a jar file to specify the paths of jar files.

JAR's MANIFEST.MF can only accept the paths as a relative style only.

When executing a JavaFX application jar, specified jar files are needed in the locations as described.

To create an executable JavaFX application jar, use javafxpackager command with -classpath option.