【JavaFX桌面应用开发】Jpackage打包篇

前言

使用JavaFX可以非常方便的开发桌面,本篇主要讲解在对JavaFX打包成windows、Linux、MacOS运行包对应的步骤以及遇到的问题解决办法。

正文

打包步骤

这里直接给出我试过,成功的打包步骤,后面再说其他步骤遇到的一些问题。
我使用的开发工具时IDEA,打包用的是Java的jpackage命令。
java版本是21.0.7。
javafx版本也是21.0.7。

准备

Java及JavaFX环境自行准备,网上资料很多,不多赘述。
windows下使用package命令时需要安装一个wix工具,3.xx版本的。
https://pan.baidu.com/s/1U0HcqU5jDAGPofxNU-bskg?pwd=3ihg

通过网盘分享的文件:wix311.exe
链接: https://pan.baidu.com/s/1U0HcqU5jDAGPofxNU-bskg?pwd=3ihg 提取码: 3ihg

安装完成后,使用小黑窗口,执行命令,看一下是否被添加到了环境变量中。

candle.exe

出现以下,说明成功。
在这里插入图片描述
否则自己添加到环境变量一下,默认的安装目录为:

C:\Program Files (x86)\WiX Toolset v3.11

1、打包所需的Maven依赖

注意:需要修改一些对应的启动类。
其中jar-with-dependencies表示会打出一个所有依赖都在一起的jar包。

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.comleader.evaluation.HelloApplication</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

2、打Maven包

正常执行clean package
在这里插入图片描述
打包结果:
在这里插入图片描述

3、打基础运行环境包

这一步,是将启动java程序所以来的环境打包成一个运行时环境包,包括所需的java环境。
打开项目路径下的cmd窗口,执行以下命令,注意修改jar包名称、javafx下的lib地址。

在这里插入图片描述

jlink --add-modules java.base,java.desktop,javafx.controls,javafx.fxml,java.logging --output target/jre --module-path "D:\env\java21\jdk\jmods;D:\env\java21\javafx\javafx-sdk-21.0.7\lib"

!!!!!注意!!!!!!
生成运行时镜像后,需要将javafx下的bin目录下的所有dll文件,复制到你生成的jre运行时环境中,否则在没有java环境的电脑上执行会因为环境缺失而报错(linux下是将javafx/lib下的所有.so文件复制)。
在这里插入图片描述

copy D:\env\java21\javafx\javafx-sdk-21.0.7\bin\*.dll target\jre\bin\
cp /opt/javafx/lib/*.so target/jre/lib/

完成
在这里插入图片描述

4、使用Jpackage打包

在项目下写一个pkg.txt,作为jpackage命令的参数
type 有几种可选类型:
app-image:免安装的exe程序
exe:安装包
rpm:linux下安装包
dmg:macos下安装包
这里以windows下的exe为例:

--name "EvalutionClient"
--type exe
--input target
--main-jar evaluation-1.0-SNAPSHOT-jar-with-dependencies.jar
--main-class com.comleader.evaluation.HelloApplication
--module-path "D:/env/java21/javafx/javafx-sdk-21.0.7/lib"
--runtime-image target/jre
--dest dist
--win-shortcut # 添加桌面快捷方式
--win-menu # 添加 "开始" 菜单快捷方式
--win-dir-chooser # 添加一个对话框,使用户能够选择安装产品的目录

还有一些其他的参数,可以支持不使用运行时环境打包等,具体可以自己查找一下参数资料。
–java-options “-Dfile.encoding=GBK” 可以添加启动jar包的参数。

Linux下:

--name "MyApp"
--type rpm
--input target
--main-jar MyApp.jar
--main-class org.springframework.boot.loader.JarLauncher
--module-path "D:/DevTools/JavaFX/javafx-jmods-21.0.7"
--add-modules javafx.controls,javafx.fxml
--module-path "D:/DevTools/Java/jdk-21/jmods"  
--add-modules ALL-MODULE-PATH
--dest dist
--linux-shortcut # 为应用程序创建一个快捷方式

Mac下:

--name "MyApp"
--type dmg
--input target
--main-jar MyApp.jar
--main-class org.springframework.boot.loader.JarLauncher
--module-path "D:/DevTools/JavaFX/javafx-jmods-21.0.7"
--add-modules javafx.controls,javafx.fxml
--module-path "D:/DevTools/Java/jdk-21/jmods"
--add-modules ALL-MODULE-PATH
--dest dist
--mac-package-identifier com.example.myapp # macOS 应用程序的标识符
--mac-sign # 对软件包或预定义的应用程序镜像进行签名

在项目和pkg.txt的目录下执行打包命令:

jpackage @pkg.txt 

等待打包完成:
在这里插入图片描述

5、运行程序,安装验证

执行这个exe,进行安装,然后启动安装好的程序,检测是否能够启动成功。
在这里插入图片描述
在这里插入图片描述
启动成功:
在这里插入图片描述

6、遇到闪退失败的问题

遇到闪退失败,大多数是因为打包时少添加了环境信息。
排查步骤:
1、先检查maven打好的jar包可否正常启动。

java -Dfile.encoding=GBK --module-path D:\env\java21\javafx\javafx-sdk-21.0.7\lib --add-modules javafx.controls,javafx.fxml  -jar evaluation-1.0-SNAPSHOT-jar-with-dependencies.jar

2、如果jar包可以正常启动,使用以下命令,用小黑窗口执行exe程序,输出错误信息到info.log,然后将错误信息提交给人工智能,询问一下怎么解决。

EvalutionClient.exe  > info.log 2>&1

我这里遇到了报错:

Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1149)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: javafx.fxml.LoadException:
file:/E:/IdeaWorkSpace/evaluation/EvalutionClient/app/evaluation-1.0-SNAPSHOT-jar-with-dependencies.jar!/fxml/SettingsView.fxml

at javafx.fxml@21.0.7/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2722)
at javafx.fxml@21.0.7/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2692)

是少添加了–add-modules java.base,java.desktop,javafx.controls,javafx.fxml,java.logging参数。
仔细的看一下其中的日志信息,然后提交给人工智能,通常都可以解决。

7、一只大坑

最一开始我打包的时候,使用的是jlink打包,命令如下:

mvn javafx:jlink 

但是因为我依赖了非模块化的jna,所以导致一直报错:
在这里插入图片描述
一直报错
错误: 自动模块不能用于来自 file:///D:/env/java21/javafx/javafx-sdk-21.0.7/lib/xxxx

搞了两天,也没有找到合适的解决方法,费了很大劲,最终整理出了以上的打包步骤,验证可行。
不要在费无用功啦~这个解决起来非常麻烦,而且会有很多坑。。。

8、两只大坑

报错:

Graphics Device initialization failed for :  d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at javafx.graphics@21.0.7/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:283)
	at javafx.graphics@21.0.7/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:253)
	at javafx.graphics@21.0.7/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:263)
	at javafx.graphics@21.0.7/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:290)
	at javafx.graphics@21.0.7/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:162)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:651)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1149)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at javafx.graphics@21.0.7/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:95)
	at javafx.graphics@21.0.7/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1149)
Caused by: java.lang.RuntimeException: No toolkit found
	at javafx.graphics@21.0.7/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:275)
	at javafx.graphics@21.0.7/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:290)
	at javafx.graphics@21.0.7/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:162)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:651)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
	at javafx.graphics@21.0.7/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	... 2 more
Failed to launch JVM

参见第三步的注意事项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老司机张师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值