Create a Linux Debian package from JavaFX 11 desktop application

As a software developer, my focus is on building Java Desktop applications for the Windows operating system.  Therefore, most of the material I produce is centered around this.  However, in this article, I am venturing into the world of Linux as I know there are many people who use Linux as their platform.

The Linux Build

For this example, I am using Debian 10.9 with the standard GUI.  This is a fresh build of the desktop machine.  I created 1 user account and set a password for the Administrator which means the root account is disabled.  I think I should point out now, I am a novice Linux user so it is highly likely I will achieve tasks in a sub-optimal manner.  For this, I beg your forgiveness.

Installing Software

Once the machine was up and running, I installed Java.  At the time of doing this installing the default JDK resulted in installing OpenJDK 11 which was exactly the version I required.  I also required JavaFX to go along with it.

I opened a command prompt and switch to the Administrator.  Before installing any software, I ran an update on the available packages and then installed the default JDK followed by OpenJFX using the commands below.

su -
apt update
apt install default-jdk
apt install openjfx
exit

Whilst I remember we will need to install “fakeroot”.  The advantage of following in the footsteps of some else is that they have learned all the hard lessons.  Installing “fakeroot” is one of those hard lessons.  When we run the application JPackager later on it will try to make use of “fakeroot” so it’s best to get this sorted out now.

su –
apt install fakeroot
exit

To complete the packaging of the OpenJDK 11 application for Linux we need to download JPackager.  For an explanation of why we need this download see an earlier article on how to package up OpenJDK11 applications for Windows.  The easiest way I found to do this was to open the Firefox browser and open the URL https://mail.openjdk.java.net/pipermail/openjfx-dev/2018-September/022500.html.

Download the Zip file option for Linux.  This contains 2 files, the jpackager command-line application, and the jdk.packager.jar file.  I extracted the 2 files and placed them in the root folder of my project which in this example I called “hellofx”.

The Source Code

I am assuming that you have a JavaFX application that will run on Java 11.  The one I used I copied from

 https://github.com/openjfx/samples/tree/master/HelloFX/CLI

and added the source code to my project folder in a subdirectory called “src”.

Next, I created a text file in the root folder of my project and called the file source.  In the file, I listed all the java files for my project.

Take note of another key learning here; If the main class in your project extends javafx.application.Application as most JavaFX applications do then you need to make a change. You will need to create another java class that is used to call the main method of your main class like this:

package hellofx;

public class Launcher {
     public static void main(String[] args) {
          HelloFX.main(args);
     }
}

My “source” file looked like this:

./src/hellofx/HelloFX.java
./src/hellofx/Lanucher.java

Building the JAR file

Our jar file will contain the compiled source code we were just looking at as well as classes from the JavaFX installation.  We will also need to know what JavaFX modules our code requires.  I found this out by looking at the “module-info.java” file which I found on the site I downloaded the source code from.  Another method to use is to build your project in an IDE and it will help you.  A third method we will talk about later in this article so keep reading.

Back to building the Jar file.  First off, we need to set a path to the JavaFX library.  Then we compile our source code into byte code which produces a series of class files.  I’m putting all my class files into a subfolder called “jarclasses”.  The commands for that look like this:

export PATH_TO_FX=/usr/share/openjfx/lib
javac –module-path $PATH_TO_FX –add-modules=javafx.controls -d jarclasses @source

As you can see from these commands, I only need the javafx.controls module; your program may well require more options.  If this is the case, then just separate the modules with a comma.

Next, we need to unpackage the JavaFX classes from their jar files and place them in the subfolder “jarclasses”.  We then just remove any “MANIFEST.MF” and “module-info.class” files that may exist in the subfolder.

cd jarclasses
jar xf $PATH_TO_FX/javafx.base.jar
jar xf $PATH_TO_FX/javafx.base.jar
jar xf $PATH_TO_FX/javafx.base.jar
rm META-INF/MANIFEST.MF
rm module-info.class
cd ..

We are now ready to create the Jar file.  We will create a jar file called “hellofx.jar” and place it in a new subfolder called “lib”.  To do this we run the following command:

jar –create –file=lib/hellofx.jar –main-class=hellofx.Launcher -C jarclasses .

To check that everything has worked correctly, and the application will run we can test it by running this command:

Java -jar lib/hellofx.jar

Packaging up the application

Here we are going to create a “DEB” installer because I’m running Debian.  You can also create an “RPM” package for Linux machines.  I will call the application “testapp” and will use the hellofx.jar file that is in the “libs” subfolder created in the previous step. The installer file will be placed in the “builddeb” subfolder.

There are two other things we need to stipulate, the module path for OpenJDK and the modules the application requires.

The third option for identifying modules required for an application is to use the Java dependencies command.  For our Jar file if we run the command like this:

jdeps –list-deps lib/hellofx.jar

And the response lists all the modules that the jar requires in order to run:

java.base
java.desktop
java.xml
jdk.unsupported

This tells us the modules we need to include when we package up.  We can now run our JPackager command with the following options, note I used full paths to avoid any issues in locating files:

/home/johnmc/hellofx/japckager create-installer “deb” –output /home/johnmc/hellofx/builddeb –input /home/johnmc/hellofx/lib –name testapp –main-jar hellofx –module-path /lib/jvm/default-java/ --add-modules java.base,java.desktop,java.xml,jdk.unsupported –version 1.2

I added a version option to the end.  I obviously had many attempts before I got everything working and if you have similar issues the version could prove handy.

Now that the application is packaged up, we can install it on our desktop.  To do this we need rights to install the software so I will run this as Administrator.  However, because I’m running as the Admin I need to use the full path to access the files.

su –
dpkg -i /home/johnmc/hellofx/builddeb/testapp-1.2.deb
exit

That’s it the application has been installed and can now be found in the applications list.

If for any reason we then want to remove the application from our desktop we can do this

su –
dpkg -r testapp
exit

 

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.