Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Packaging: jlink and jpackage

The notebook's user has no JDK, no Maven and no JavaFX libraries. They need a folder with the program or an installer. The JDK has two tools for this. jlink builds a trimmed Java runtime: only the modules the application needs, together with the application itself. jpackage wraps such a runtime in a familiar form: a program with an .exe file or an .msi, .dmg or .deb installer.

Why modules matter

jlink works only with named modules: every library must have its own module-info. JavaFX 25 and Jackson 3 have one, so our project builds without changes. From the requires lines in module-info.java jlink finds everything it needs and takes nothing extra.

Configuring the plugin

javafx-maven-plugin can call jlink. Add the parameters to its configuration:

<!-- pom.xml — the javafx-maven-plugin plugin -->
<plugin>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>0.0.8</version>
    <configuration>
        <mainClass>com.example.notes/com.example.notes.App</mainClass>
        <options>
            <option>--enable-native-access=javafx.graphics</option>
        </options>
        <launcher>notes</launcher>
        <jlinkImageName>notes</jlinkImageName>
        <jlinkZipName>notes</jlinkZipName>
        <stripDebug>true</stripDebug>
        <noHeaderFiles>true</noHeaderFiles>
        <noManPages>true</noManPages>
    </configuration>
</plugin>
ParameterWhat it does
launcherThe name of the launch script in the bin folder
jlinkImageNameThe name of the image folder in target
jlinkZipNameAlso pack the image into a zip archive
stripDebug, noHeaderFiles, noManPagesDrop debug information, C header files and man pages

Building the image

mvn clean javafx:jlink

Maven compiles the project and runs jlink. At the end you see Building zip: ...\target\notes.zip and BUILD SUCCESS. The warning The 0 argument for --compress is deprecated comes from jlink itself in response to an option the plugin passes; it does not affect the result. target now holds a notes folder of about 100 MB and a notes.zip archive of about 32 MB. Inside target/notes/bin are Java, the needed libraries and the notes and notes.bat launch scripts:

target/notes/bin/notes

On Windows run target\notes\bin\notes.bat. The same window opens as with mvn javafx:run. The folder or the archive can be copied to another computer with the same operating system; it does not need Java.

A program and an installer

jpackage is part of the JDK. It takes the ready image and turns it into an ordinary program:

jpackage --type app-image --name Notes --runtime-image target/notes --module com.example.notes/com.example.notes.App --java-options --enable-native-access=javafx.graphics --dest target/dist

target/dist/Notes now contains Notes.exe (Notes.app on macOS), which opens the window without a console. The app-image type is just a folder. For an installer, change --type:

SystemTypesWhat else you need
Windowsexe, msiWiX Toolset
macOSdmg, pkgXcode command line tools
Linuxdeb, rpmdpkg or rpm-build

jpackage builds a package only for the system it runs on: a Windows installer is made on Windows, a macOS one on a Mac. Use --icon for an icon and --app-version for the version.

Common mistake

If even one library is not modular, jlink stops: Error: automatic module cannot be used with jlink: jsr305 from file:///.../jsr305-3.0.2.jar. Such a library is replaced with a modular version or an alternative. If there is no replacement, you are left with an ordinary launch through java: the whole application goes on the classpath, and JavaFX is added as modules with the --module-path and --add-modules options.

Thanks for reading!

Donate to the site — we work hard for you.