JPackaged JavaFX + Spring boot 不启动

Posted

技术标签:

【中文标题】JPackaged JavaFX + Spring boot 不启动【英文标题】:JPackaged JavaFX + Spring boot does not launch 【发布时间】:2021-11-27 12:38:31 【问题描述】:

我正在尝试使用 Spring Boot 构建 JavaFX 应用程序并使用 jpackage 进行部署。

当使用javafx-maven-pluginjavafx:run 命令时,我可以看到项目正在启动。但是在将其构建到*.msi 安装程序、安装并启动*.exe 之后,什么也没有发生(无论是通过双击还是命令行运行)。

我该如何解决这个问题,或者至少知道发生了什么? 我怀疑 javafx:run 目标有一些手动 jlink 中缺少的参数,但是我不能使用 javafx:jlink 因为应用程序本身不是一个模块,因为 Spring Boot 还没有模块化。

这里是来源;

编辑: 根据@Slaw 的建议,我修改了jpackage 命令以包含`--win-console。哪个成功运行了应用程序。虽然这是一个很棒的步骤,但这不是我想要的,我想在没有提示的情况下运行它。

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.test</groupId>
    <artifactId>mytest</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.0</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.6.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.0</version>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <configuration>
                    <mainClass>org.test.Main</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>$project.build.directory/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

主要:

package org.test;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main extends Application 
    private ConfigurableApplicationContext springContext;
    private Parent rootNode = new AnchorPane();
    public static void main(String[] args) 
        Application.launch(args);
    
    @Override
    public void start(Stage stage) throws Exception 
        stage.setScene(new Scene(rootNode, 700, 700));
        stage.setMinWidth(700);
        stage.setMinHeight(700);
        stage.show();
    
    public void init() throws  Exception
        springContext = SpringApplication.run(Main.class);
    
    public void stop() throws Exception
        springContext.close();
    

我的构建脚本是:

@ECHO OFF
SETLOCAL
call mvn clean install
set manual_modules=,javafx.controls,javafx.graphics,javafx.fxml
for /f %%i in ('jdeps --multi-release 17 --ignore-missing-deps --print-module-deps --class-path "target/lib/*" target/classes/org/test/Main.class') do set detected_modules=%%i
echo jlink
jlink --no-header-files --no-man-pages --compress=2 --strip-debug --module-path "target/lib" --add-modules %detected_modules%%manual_modules% --output target/java-runtime
echo jpackage
jpackage --type msi --dest target/installer --input target --name mytest --main-class org.test.Main --main-jar mytest-1.0.jar --runtime-image target/java-runtime
endlocal
@ECHO ON

【问题讨论】:

不知道有没有用,但是你可以尝试打包--win-console,然后从控制台运行*.exe(可能需要告诉你的控制台等待而不是新建一个窗口,不确定),并希望会发出一个堆栈跟踪,告诉你出了什么问题。 @Slaw Sooo ..我尝试了您的方法并希望获得堆栈跟踪。没想到,我没有收到错误。该应用程序运行并成功启动。看起来在控制台中运行它可以使它工作。然而,这并不是一个很好的用户体验。我会更新问题 有趣。很抱歉,但我不知道为什么会发生这种情况,至少目前不会。 【参考方案1】:

我无法解释为什么第一个jpackage 命令与--win-console 一起工作,而不是没有。我不明白的事情一定发生在幕后(如果有人知道,我仍然对那个答案感兴趣!)。

无论如何,经过一些调试和多次尝试,我设法生成了exe

    通过 Spring Boot Loader 启动应用程序,这意味着 jpackage 命令现在是: jpackage --type msi --dest output/installer --input target --name testing --main-class org.springframework.boot.loader.PropertiesLauncher --main-jar mytest-1.0.jar --runtime-image target/java-runtimepom.xml中添加spring boot loader依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-loader</artifactId>
    <version>2.6.0</version>
</dependency>
    修改spring-boot-maven-plugin配置:
           <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.6.0</version>
                <configuration>
                    <mainClass>org.test.Main</mainClass>
                    <layout>ZIP</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

我承认我在这里所做的是相当实验性的(至少对我而言),所有可以提供更深入了解、参考或更好方法的答案都将受到欢迎。

【讨论】:

多么宝贵的帮助。非常感谢。

以上是关于JPackaged JavaFX + Spring boot 不启动的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Spring Boot 解析 JavaFX 应用程序的占位符

JavaFX 应用程序中的 Spring 应用程序上下文

无法使Spring Boot + JavaFX在Eclipise中运行

我应该怎么做才能获得我的 javafx spring boot 桌面应用程序的 OAuth2 访问令牌?

javafx已经没多少用了

eclipse安装好javaFX插件后新建javaFX project报错,javaFX不能import,求解决。