I am trying to run a sample application that integrates JavaFX and Spring Boot, working with Intellij and Gradle. To achieve the integration I am testing Gluon Ignite using their Spring Boot Sample from the Wiki.
I run the application as a Spring Boot application (bootRun
task in Gradle) but get the error
JavaFX runtime components are missing, and are required to run this application
which clearly says that JavaFX components are not in the module path. This error does not happen if I run the application as a JVM app (task Run
), but obviously the Spring Boot part does not work (tested on a more complex version using Spring Boot WebSocket components).
Which is the right way to have the Spring Boot app to run with the JavaFX runtime components correctly added to the module path?
In a normal run the org.javamodularity.moduleplugin
takes care of everything, but in the boot run it does not work apparently.
Here below the relevant elements.
build.gradle
plugins {
id 'application'
id 'org.springframework.boot' version '3.0.2'
id 'io.spring.dependency-management' version '1.1.0'
id 'org.javamodularity.moduleplugin' version '1.8.12'
id 'org.openjfx.javafxplugin' version '0.0.10'
}
javafx {
modules = ['javafx.controls','javafx.fxml']
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.gluonhq:ignite-spring:1.1.0'
implementation 'javax.inject:javax.inject:1'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:webjars-locator-core'
implementation 'org.webjars:stomp-websocket:2.3.3'
implementation 'org.webjars:bootstrap:3.3.7'
implementation 'org.webjars:jquery:3.1.1-1'
}
application {
mainModule = "com.my.ignite"
mainClass = "com.my.ignite.SpringBootApp"
}
module-info
module com.my.ignite {
requires javafx.controls;
requires javafx.fxml;
requires javafx.graphics;
requires javafx.base;
requires spring.messaging;
requires spring.web;
requires spring.context;
requires spring.boot.autoconfigure;
requires spring.boot;
requires spring.websocket;
requires spring.beans;
requires javax.inject;
requires ignite.spring;
exports com.my.ignite;
opens com.my.ignite;
}
The application code:
package com.my.ignite;
import com.gluonhq.ignite.spring.SpringContext;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import java.io.IOException;
import java.util.Arrays;
@SpringBootApplication
@ComponentScan("com.gluonhq.ignite.spring")
public class SpringBootApp extends Application implements ExampleApp {
public static void main(String[] args) {
Application.launch(SpringBootApp.class, args);
}
@Autowired
private FXMLLoader fxmlLoader;
// Originally in the sample code:
// private final SpringContext context = new SpringContext(this);
// Modified (see "Basic Spring Sample" code):
private final SpringContext context = new SpringContext(this,
() -> Arrays.asList(SpringBootApp.class.getPackage().getName()));
@Override
public void start(Stage primaryStage) throws IOException {
// Originally in the sample code:
// context.init(() -> SpringApplication.run(SpringBootApp.class));
// Modified:
context.init();
fxmlLoader.setLocation(getViewLocation());
Parent view = fxmlLoader.load();
primaryStage.setTitle("Spring Boot Example");
primaryStage.setScene(new Scene(view));
primaryStage.show();
}
}