0

I've successfully created an executable file of my JavaFX maven project using jpackage on Netbeans on Linux:

./jpackage --input ~/Documents/NetBeans/MyFX/target/ --dest ~/Documents/NetBeans/MyFX/ --name "MyFX" --main-jar MyFX-2.0.jar --main-class my.myfx.App --icon ~/Documents/NetBeans/MyFX/mypic.png --add-modules javafx.controls,javafx.fxml

The program installs fine, but on running from terminal, it gives following error: (trimmed it down for relevance)

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml@19/javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
    at javafx.fxml@19/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
.
.
.
Caused by: java.lang.NoClassDefFoundError: java/sql/DriverManager
    at my.myfx.DB.init(DB.java:22)
    ... 50 more
Caused by: java.lang.ClassNotFoundException: java.sql.DriverManager
    ... 57 more

The line in question is:

java.sql.Conection conn;
String fileName="a.db";
**conn=java.sql.DriverManager.getConnection("jdbc:sqlite:"+fileName);**

Here's module-info:

module my.myfx {
    requires javafx.controls;
    requires javafx.fxml;
    requires java.logging;
    requires java.base;
    requires java.sql;
    requires org.apache.poi.poi;
    requires org.apache.poi.ooxml;
    requires jarchivelib;

    opens my.myfx to javafx.fxml;
    exports my.myfx;
}

POM inclusions

javafx-controls
javafx-fxml
maven-jar-plugin
maven-dependency-plugin
javafx-maven-plugin
  • You are using `jdbc:SQLite`, but do not use the SQLite jdbc driver in your module info. You probably should require it there. My guess is that you also have some additional issues as noted in other answers and comments and some other issues not noted there. – jewelsea Jan 07 '23 at 21:47

3 Answers3

0

It seems that java.sql is missing in the --add-modules list. There may be even more modules missing. I am not sure whether jpackage extracts anything from the module-info.java

Instead of doing this manually it might also be a good idea to follow this tutorial: https://github.com/dlemmermann/JPackageScriptFX

mipa
  • 10,369
  • 2
  • 16
  • 35
0

The --main-jar/--main-class options should not be used for modular applications. In this case you will get a runtime image with only the javafx.controls and javafx.fxml control modules (and their dependencies).

Use the --module option instead:

--module -m <module name>[/<main class>]
      The main module (and optionally main class) of the application
      This module must be located on the module path.
      When this option is specified, the main module will be linked
      in the Java runtime image.  Either --module or --main-jar
      option can be specified but not both.

The command would be:

./jpackage
  --input ~/Documents/NetBeans/MyFX/target/
  --dest ~/Documents/NetBeans/MyFX/
  --name "MyFX"
  --module my.myfx/my.myfx.App
  --icon ~/Documents/NetBeans/MyFX/mypic.png

You might also need to add the folder with the jar to your module path with --module-path/-p.


For maven in particular, you can generate a directory with all the needed jars using a combination of the dependency and resource plugins. The following configuration worked for me:

<project ...>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-deps</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/mods</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.2</version>
        <executions>
          <execution>
            <id>copy-app-jar</id>
            <phase>package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}/mods</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.build.directory}</directory>
                  <includes>
                    <include>${project.build.finalName}.${project.packaging}</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
  </build>
</project>

Note that I had to remove the <pluginManagement>/</pluginManagement> lines per https://stackoverflow.com/a/9850734 to get the dependency plugin to execute. (I'm not a maven expert, so there might be a better way to do this, but it should work)

Then running mvn package creates a mods folder that I can pass to --module-path when running jpackage.

Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • The folder containing my jar is also `~/Documents/NetBeans/MyFX/target/MyFX-2.0.jar`. After I added this line to the command you suggested, I get the error: Bundler DEB Bundle skipped because of a configuration problem: java.lang.module.FindException: Two versions of module my.myfx found in ~/Documents/NetBeans/MyFX/target (classes and MyFX-2.0.jar) – JavaUser007 Jan 07 '23 at 19:25
  • @JavaUser007 Everything in the directory passed to `--input` is packaged into the application. You should probably create a new input directory with just the files that should be packaged into the application. – Jorn Vernee Jan 07 '23 at 20:19
  • @JavaUser007 Sorry, that goes for the directory passed to `--module-path`/`-p` as well. It looks like it's failing because the target directory contains both the modular jar file and the compiled classes which includes also a second `module-info.class` file for `my.myfx`. Making the `my.myfx` module appear twice on the module path. So, you should create a directory with just the modular jar file and it's dependency jars, and then pass that to `--module-path`. – Jorn Vernee Jan 07 '23 at 20:46
  • This folder `/mod` contains jars required by my project, which has sqlite-jdbc, poi-ooxml, javafx-base, javafx-fxml, etc. I copied my main jar (`MyFX-2.0.jar`) inside it. Should I copy `jmod` files for java.sql in it too? – JavaUser007 Jan 08 '23 at 13:26
  • @JavaUser007 It's a JDK module, so it should be picked up automatically by jpackage. If it isn't picked up you can add another `--module-path` flag that points to the JDKs jmods folder (no need to copy the .jmod file, although that should also work) – Jorn Vernee Jan 08 '23 at 14:28
0

I downloaded .jmod files for JavaFX from https://gluonhq.com/products/javafx/ and copied them in JDK's jmod folder. This folder also contains java.sql.jmod file, which is required here. Then running the command:

./jpackage --input ~/Documents/NetBeans/MyFX/target/
--dest ~/Documents/NetBeans/MyFX/
--name "MyFX" --main-jar MyFX-2.0.jar
--main-class my.myfx.App
--icon ~/Documents/NetBeans/MyFX/myicon.png
--add-modules javafx.controls,javafx.fxml,java.sql
--module-path ~/Setups/OpenJDK-19/javafx-jmods/

I couldn't get it to compile with the --module flag though.