dlemmermann / JPackageScriptFX

A tutorial project featuring a build script (Mac, Windows) for JavaFX applications based on the new jpackage tool.
https://www.dlsc.com
Apache License 2.0
226 stars 27 forks source link

Can't run a simple packaged JavaFX app that reads the UI from an external FXML file (XMLStreamException) #15

Closed juananpe closed 2 years ago

juananpe commented 2 years ago

Hi,

First: thanks for setting up and maintaining this project.

Let me explain my problem here. I tried the vanilla JPackageScriptFX and it works perfectly. I have seen that the JavaFX app used in the example just generates its UI programatically (a label, a box, and a scene). I tried to package it in Linux, macOS and Windows and it works. So far so good.

But now, I'm trying to package a JavaFX app that dynamically loads the FXML UI (reading from a .fxml file) It is just a project created following the IntelliJ template (wizard) for a new JavaFX project, nothing fancy. I can run the application from IntelliJ and it works like a charm.

The project is here: https://github.com/juananpe/packaging

Now, when trying to generate the installer, the JPackageScriptFX provided scripts run flawlessly. But, when I try to run the application (double clicking on the app icon, I'm using macOS), it tries to open a window... that is immediately closed. Usually this means that it is throwing some sort of exception so I tried to run it from the terminal. And, as suggested, I got this exception:

juanan@u033782  /Applications/Packaging.app/Contents/MacOS $ ./Packaging
May 06, 2022 1:15:36 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @48724d24'
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:901)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
    at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException
    at com.example.packaging.HelloApplication.start(HelloApplication.java:13)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Caused by: java.lang.ClassNotFoundException: javax.xml.stream.XMLStreamException
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    ... 7 more
Failed to launch JVM

I have searched SO trying to guess what is happening there (tried searching for combinations of NoClassDefFoundError, XMLStreamException, jar file, JavaFX), but I couldn't find anything useful. I would really appreciate any help here.

mipastgt commented 2 years ago

Good point. I got your program working by just extending the list of manual_modules like this:

manual_modules=,jdk.crypto.ec,jdk.localedata,java.xml,java.scripting,jdk.unsupported

These additional modules cannot be found by the static analysis because they are used by the FXML reader via reflection.

juananpe commented 2 years ago

Oh! It works! Thanks for your promptly answer. I guess that java.xml and java.scripting dependencies were not detected by jdeps, and I should be able to figure out the name of those modules (and add them manual_modules), but how did you know about jdk.unsupported?

mipastgt commented 2 years ago

I tested your project on my Mac. Therefore I removed the option --strip-native-commands from the jlink command in the script file build_app_mac.sh so that I could add the following script as runApp.sh in the root folder of your project.

#!/bin/bash

target/java-runtime/bin/java \
-cp "target/installer/input/libs/*" \
com.example.packaging.Main

After rebuilding your project I could then launch this script which only depends on whatever the build has created. So, if something is missing I would get an error message. That way I discoverd that javax.xml.stream.XMLStreamException is missing which is located in java.xml. After I added that and repeated the procedure I found that javax.script.Bindings is still missing which resides in java.scripting. After the next iteration I already got a black window but sun.misc.Unsafe was still missing which is in jdk.unsupported.

That's the whole story. Nothing special.

mipastgt commented 2 years ago

As the problem seems to be resolved I will close the issue.

juananpe commented 2 years ago

Thanks! I learned a lot trying to solve this issue and reading your explanations :)