I have a program written in Clojure and JavaFX back in 2014. A dependency for the program was revised recently to use Java 17. Simply substituting the new version of the dependency produces an error related to not being able to read the new class file format. I would like to update the application but have not been able to generate an uberjar with current versions of Java (17) and JavaFX (17.0.1).
Here are the project.clj
and source file for an SSCCE.
(defproject sutest "0.1.0-SNAPSHOT"
:description "Test for including JavaFX components in uberjar"
:dependencies [[org.clojure/clojure "1.10.3"]
[org.openjfx/javafx-controls "17.0.1"]]
:aot :all
:main sutest.core)
(ns sutest.core
(:gen-class
:extends javafx.application.Application)
(:import
[javafx.application Application Platform]
[javafx.event EventHandler]
[javafx.geometry Insets Pos]
[javafx.scene Scene]
[javafx.scene.control Button Label]
[javafx.scene.layout VBox]))
(defn -start [this stage]
(let [hiLbl (Label. "Hello World!")
exitBtn (Button. "Exit")
root (VBox. 12.0)]
(.setOnAction exitBtn (reify EventHandler (handle [_ _]
(Platform/exit))))
(.setPadding root (Insets. 0 10 0 10))
(.addAll (.getChildren root) [hiLbl exitBtn])
(.setAlignment root Pos/CENTER)
(.setScene stage (Scene. root 250 150)))
(.show stage))
(defn -main [& args]
(Application/launch sutest.core args))
The program works as expected when executed directly with lein run
or from an IntelliJ IDEA/Cursive "run" configuration. Running lein uberjar
completes without errors, but attempting to run the uberjar with
java -jar target/sutest-0.1.0-SNAPSHOT-standalone.jar
produces
Error: JavaFX runtime components are missing, and are required to run this application
I'm using Leiningen 2.9.6 because of this issue with 2.9.7. When running the program, Leiningen builds a classpath containing the needed jars in the local dependency repository.
I've seen a few questions about including the newer JavaFX modules in "fat" jars for Java and tried including them in the Leiningen build. Few related to Clojure and Java. For example, see the project.clj
for the fn-fx library. That resorts to a special "leaky" profile to include the modules. That didn't work for me for some reason.
I've tried adding the modules to the IDEA/Cursive project. That correctly downloaded the modules in the project information, but still does not build an uberjar with the modules.
I've fiddled with the "Artifacts" section of the IDEA/Cursive project too. But that was unsuccessful.
There are tutorials on the Gluon site that walk through making a "fat" jar containing the JavaFX components, but those are directed towards Java projects.
Can Leiningen be used to create an uberjar containing the dependencies?
If not Leiningen, how about tools.deps or boot?
Has anyone been successful falling back to a plain Maven build by adapting the Gluon instructions?