当前位置: 首页 > news >正文

Java 21 或 JavaFX 打包 exe 之 GraalVM Native Image 方案

JavaFX 打包 exe 的方法有很多,总结起来,大概可分为 3 种方案

方案一:Java 运行时 + exe 启动器

该方案的通用性很好,但是有一个缺点是生成的包很大,因为它整个JDK环境放进包里了,比如 jdk21 解压后的大小就是300M,再加上项目文件和各种依赖,就会更大。
实现步骤,以 jpakage 为例:

步骤1:打包成 Fat Jar

首先把项目打包成一个可运行Fat Jar,在这jar中包含了所有依赖和main入口
Spring Boot Maven 插件可以参考:Spring Boot Maven Plugin
我这里使用的是Gradle 的 shadow 插件,配置如下

plugins {id("java")id("com.gradleup.shadow") version "9.2.2"
}

执行插件

.\gradlew clean shadowJar

结果将生成文件:D:\projiects\summary\build\libs\summary-1.0-all.jar
文件大小为 9M,因为功能仅仅只是创建一个窗口,显示一行文字
执行命令java -jar summary-1.0-all.jar 可直接运行 jar 包,如图
在这里插入图片描述

步骤2:打包成 app-image
jpackage --type app-image -n App --input .\build\libs\ --main-jar summary-1.0-all.jar --dest .\build\ --icon logo.ico

打包镜像成功后,App 镜像中包括了Java21的运行时 runtime,和可执行程序 App.exe。大小总共有 206M,如图
在这里插入图片描述

步骤3:打包为安装程序

需要先安装wix314.exe,然后再执行步骤2的命令,去掉其中参数 --type app-image

jpackage -n App --input .\build\libs\ --main-jar summary-1.0-all.jar --dest .\build\ --icon logo.ico

其实真没有必要打安装包,不如直接打个 7z 格式的压缩包,大小只有 52M
在这里插入图片描述

方案二:采用Java模块化开发

Java 模块化项目与非模块化的项目区别就是多了一个 module-info.java 文件,里面有依赖声明 require 和访问权限声明 export 与 open。
使用 jlink 可以创建一个最小化 Java 运行时镜像 runtime-image。
使用 jpackage 可以基于这个定制的 runtime-image(而非完整的JDK)打包。
这样打包如JDK21,解压之后的大小有100M,比方案一的200M小了很多。
但是有些依赖并非模块的jar包,Java 就引入了 未命名模块自动模块 2个概念来兼容非模块化依赖,但是也可能出现无法兼容的问题,就需手动修改jar包了。
把非模块化jar修改成模块化jar,即:添加module-info,步骤如下:

  1. 使用 jdeps 分析jar包的依赖项
  2. 根据自己的理解创建 module-info.java
  3. 使用 javac 命令把 module-info.java 编译成 module-info.class
  4. 使用 jar 命令把 module-info.class 添加到你所修改的 jar 文件中去
    这一看就是一件很繁琐的事情,需要你对该 jar 包有一定了解,所以该方案 的通用性并不好。

下面我们通过 gradle 插件来执行 jlink 与 jpackage

步骤1:配置插件
plugins {id("org.beryx.jlink") version "3.1.4-rc"
}
jlink {forceMerge("log4j-api")options.set(listOf("--strip-debug", "--no-header-files", "--no-man-pages"))launcher {name = "summary"jvmArgs = listOf("--add-op
http://www.dtcms.com/a/437988.html

相关文章:

  • 1.2.3 MCP(Model Context Protocol)
  • dede网站栏目管理网络科技是做什么的
  • 《Gdb 调试实战指南:不同风格于VS下的一种调试模式》
  • lua虚拟机的垃圾回收机制
  • 网站建设需要的材料wordpress自带的404
  • MPAndroidChart 用法解析和性能优化 - Kotlin Java 双版本
  • Qt中使用日志---Log4Qt
  • linux centos 7 解决终端提示符出现-bash-4.2的问题
  • MCP模型上下文协议实战:个人应用项目如何集成MCP?
  • Vue--Vue基础(一)
  • 外贸网站推广如何做郑佩佩 最新消息
  • 用VScode和msys2配置C/C++和wxWidgets
  • 【升级安卓9教程】华为Q21_Q21A_Q21C_Q21AQ_Q21AE_hi3798mv200线刷烧录包带adb权限
  • vite vue 打包后运行,路由首页加载不出来
  • 《C++ STL:vector类(下)》:攻克 C++ Vector 的迭代器失效陷阱:从源码层面详解原理与解决方案
  • 微软Agent框架深度解析:重新定义AI应用开发的革命性架构
  • 微信看视频打赏网站建设项目立项流程图
  • 爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
  • [工作流节点8] 更新记录节点应用案例 —— 业务自动化的关键一环
  • MySQL表的内连和外连
  • go 基础
  • 鸿蒙开发3--UI布局(玩转鸿蒙的Row、Column与Stack容器)
  • 为什么要给企业建设网站做单位网站
  • ML4T - 第7章第8节 利用LR预测股票价格走势Predicting stock price moves with Logistic Regression
  • 性能之巅:大小水管问题深究
  • css选择器(继承补充)
  • 郑州高新区做网站的公司聚美优品的电子商务网站建设论文
  • uniapp集成语音识别与图片识别集成方案【百度智能云】
  • SpringCloud API Gateway2.0如何解决docker中应用间IP漂移的正确手法
  • 鸿蒙Next中使用mDNS发现局域网服务:完整指南与实战