I've been migrating all my JavaFX applications to Java 15 / JavaFX 15.0.1 to see if there are any pain points or gotchas to be aware of. I particularly wanted to understand how Maven and Gradle handle JavaFX, and how to successfully build and run the applications in IntelliJ IDEA.
In this blog post I explore the steps taking to upgrade a Spring Boot/Maven/JavaFX application.
Backstory
Once upon a time, in the olden days when we were allowed to physically go to conferences, Josh Long and I decided to co-present at Code One (2018). Obviously this was going to be a Spring Boot application, and Josh suggested we create a JavaFX front end for it, since that's what I'd been using in two previous demos (Java 8 in Anger and Real World Java 9).
I mutated and update this a bit and presented it (solo) at Spring One in 2019, and turned that into a step-by-step video-and-blog IntelliJ IDEA tutorial.
The application started off as a Java 11 / JavaFX 13 application in the first place, and it was all running correctly in IntelliJ IDEA 2020.3, so there wasn't too much work in updating it. The app uses Maven, unlike the other applications I've blogged about.
Steps
Kotlin Service
The application relies on a Kotlin Spring Boot back end, which I upgraded before touching the JavaFX UI.
- Updated to latest Kotlin version (1.3.61 -> 1.4.21)
- Updated to latest Spring Boot version (2.2.2.RELEASE -> 2.4.1, I had to go and do a quick Google to make sure the version number format had changed, and indeed it had).
- Removed
junit-vintage
exclusion from thepom.xml
, apparently this is no longer required since Spring Boot 2.4.1, which is nice. - Merged a pull request, and made some changes to their changes. A pull request! Full of tests! Lovely.
The back end needed very little attention and it was good to go.
Spring Boot Client Code & JavaFX UI
-
Had to tell Spring boot to skip the repackage on the client module (this module is a library with autoconfiguration enabled that's used by the UI module) , because otherwise the build wasn't working. I'll be honest, I'm not sure exactly why...
true -
Updated Spring Boot (2.2.2.RELEASE -> 2.4.1) in the client module. This meant I had to stop using removed deprecated methods (
retryBackoff
) and use the new ones. Also removed the now-redundant exclusion of thejunit-vintage
engine. -
Updated client to Java 15.
-
Changed UI module pom.xml to use the JavaFX plugin (previously it was just declaring JavaFX dependencies)
org.openjfx javafx-maven-plugin 0.0.5 com.mechanitis.demo.stockui.StockUiApplication -
Updated to JavaFX 15.0.1.
-
Updated Spring Boot (2.2.2.RELEASE -> 2.4.1) in the UI module and removed exclusion of the
junit-vintage
engine. -
Set Java version in pom.xml to Java 15. Made sure IntelliJ IDEA was also using this as the SDK and the language level.
-
Final step, which was not required: using javafx-weaver to provide the JavaFX / Spring integration, instead of doing it all in the application. It made the code a bit simpler.
Running the Application
This application runs from the command line (or IntelliJ IDEA terminal window) with:
./mvn javafx:run
(You will need a JAVA_HOME
that points to JDK 15 since that's the version that I told Maven to use)
If your system-wide JAVA_HOME
(i.e. not your IntelliJ IDEA Project SDK) is set to a value lower than 15 (for example mine is set to Java 11 by default), you can not run it by calling the same target from the Maven tool window. This limitation is mentioned in my IntelliJ IDEA blog post, under the Maven section.
You can quite happily run the application from the editor, either from the green arrows in the gutter, or via ⌃⇧R (MacOS) or Ctrl+Shift+F10 (Windows).
Resources
- Code on GitHub
- Videos, slides and more info on the application
- OpenJFX Getting Started Documentation
- Spring Boot
See also: