I have a JavaFX project with dependencies on SQLite
and POI
, so I used maven-dependency-plugin
to copy all dependencies in target\lib
folder. That folder contains about 21 dependencies common-codecs, curvesapi, javafx-base, javafx-fxml...
etc.
To create a jpackage I'm using jpackage-maven-plugin
to create an installer. I have jmods
folder copied to java.home
. The POM is as follows:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>19</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.39.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<launcher>App</launcher>
<mainClass>com.example.App</mainClass>
</configuration>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<mainClass>com.example.App</mainClass>
</configuration>
</execution>
<execution>
<id>debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option>
</options>
</configuration>
</execution>
<execution>
<id>ide-debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
</options>
</configuration>
</execution>
<execution>
<id>ide-profile</id>
<configuration>
<options>
<option>${profiler.jvmargs.arg1}</option>
<option>${profiler.jvmargs.arg2}</option>
<option>${profiler.jvmargs.arg3}</option>
<option>${profiler.jvmargs.arg4}</option>
<option>${profiler.jvmargs.arg5}</option>
</options>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.panteleyev</groupId>
<artifactId>jpackage-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<name>ExampleFX</name>
<appVersion>${project.version}</appVersion>
<icon>${basedir}/icon.ico</icon>
<vendor>Myself</vendor>
<destination>Runtime</destination>
<modulePaths>
<modulePath>C:\Program Files\Java\jmods</modulePath>
<modulePath>${project.build.directory}/classes</modulePath>
</modulePaths>
<module>com.example/com.example.App</module>
<runtimeImage>${java.home}/lib</runtimeImage>
<winDirChooser>true</winDirChooser>
<winShortcut>true</winShortcut>
<winConsole>true</winConsole>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>19</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
This command neither packages the lib
folder in the installer, nor does it properly copies JVM, as on running the program, it gives Failed to find JVM in "C:\Program Files\Example\runtime" directory.
error. Any help appreciated.
EDIT
Changed some parameters:
from<runtimeImage>${java.home}/lib</runtimeImage>
to <runtimeImage>${java.home}</runtimeImage>
,
added module path <modulePath>${project.build.directory}/lib</modulePath>
Now the app fails to find modules (dependencies) which are present in ${INSTALLDIR}/app/mods
. Trying to add these modules require I remove runtimeImage
parameter. If I do so:
<addModules>javafx.fxml,javafx.controls,
org.apache.poi.ooxml,org.apache.poi.poi,org.xerial.sqlitejdbc,SparseBitSet,
org.apache.commons.compress,org.apache.commons.codec,org.apache.commons.collections4,
org.apache.commons.io,com.github.virtuald.curvesapi,commons.math3,
org.apache.commons.collections4,org.apache.xmlbeans</addModules>
I always get error regarding any module randomly:
jlink failed with: Error: automatic module cannot be used with jlink: commons.math3 from file:///C:/Users/MY/Documents/NetBeansProjects/Example/target/lib/commons-math3-3.6.1.jar
module-info
module com.example{
requires javafx.controls;
requires javafx.fxml;
requires javafx.base;
requires javafx.graphics;
requires java.logging;
requires java.base;
requires java.sql;
requires org.apache.poi.poi;
requires org.apache.poi.ooxml;
requires org.apache.commons.codec;
requires org.apache.commons.collections4;
requires org.apache.commons.compress;
requires org.apache.commons.io;
requires commons.math3;
requires com.github.virtuald.curvesapi;
requires org.apache.logging.log4j;
requires SparseBitSet;
requires org.xerial.sqlitejdbc;
requires org.apache.xmlbeans;
opens com.example to javafx.fxml;
exports com.example;
}
Use JPackageScriptFX. Here's how to use it:
(I'll refer to JPackageScriptFX as JPS
and your project as Example
)
<modules>
section. Remove all existing module entries (jpackagefx-main,jpackagefx-module1,jpackagefx-module2
). Write <module>Example</module>
instead.groupId
to Example's groupId.artifactId
.<packaging>jar</packaging>
beneath <version>
tag.jpackagefx-main
's maven-dependency-plugin from its POM and copy it to Example's POM.<configuration><mainClass>com.example.App</mainClass></configuration>
in javafx-maven-plugin if it isn't there already.<profiles>
section from jpackagefx-main and copy it to Example's POM.${client.version}
to ${project.version}
in <APP_VERSION>
and <PROJECT_VERSION>
(This is required especially in the case of Linux, otherwise the jpackage will fail in final stages (dpkg-deb returns with error code 2)).package com.example
public class AppLauncher{
public static void main(String[] args){
App.main(args);
}
}
build_app_linux.sh
, build_app_mac.sh
or build_app_windows.bat
file inside Example's project folder. I'll refer to the linux version in the next steps, you can find appropriate lines in other platform files.MAIN_JAR="main-ui-...
to MAIN_JAR="Example-...
or whatever the name of your Jar file is (You can find Jar filename by building the project and simply looking its name in target
folder).target/classes/com/Example/App.class
,java.sql
)."
to give space in the name.com.example.AppLauncher
.--print-module-deps target\classes\com\example\App.class > temp.txt
.target\installer