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

java客户端_大家都是怎么发布Java客户端程序的?难道让用户自己装JRE?

JDK 9 以及更高版本的 JDK 以及拥有了一个叫做 jlink 的实用工具,能够将 JDK 和程序模块一起打包,做成一个小型的 jre。

对于一个简单的 hello world 程序,jlink 生成的 JRE(Linux x86_64,版本号为 11.0.5)大小只有41M,简单的用zip命令压缩一下就只剩16MB了,一般简单的命令行应用体积就在这个级别。Windows 上的小工具还可以考虑用 32 位的 JRE,最后生成的程序大小,以及占用的内存都还会小一截。

对于复杂一些的应用,可以参考一下我的ClassViewer/ClassViewer​github.com

这是一个 JavaFX 应用,依赖(包括间接依赖)的模块有java.base、java.datatransfer、java.xml、java.prefs、java.desktop、javafx.base、jdk.unsupported、javafx.graphics、javafx.controls和jdk.zipfs,经过 jlink 以及压缩后的效果是这样

作为9102年的 GUI 应用,这个体积完全合格,捆绑 JRE 发布还能避免用户 JRE 版本老旧(决定捆绑 JRE 后,ClassViewer v4 已经开始用 Java 13 开发了,并且做好了每次 Java 新版本发布都在第一时间迁移到最新版本的准备)或者是不支持 JavaFX,我觉得这是目前很理想的一种发布方式了。

如果你的项目使用 Gradle 作为构建工具,推荐用 badass jlink 插件来调用 jlink。

目前有大量库作为自动模块发布,而 jlink 要求依赖的模块拥有 module-info,不支持自动模块,badass jlink 插件在不需要对源码做任何修改解决了这个问题。插件会将所有自动模块内容全部解压合并到一个模块中,再为每个自动模块生成一个对应的空模块,在空模块中声明对合并模块的 requires transitive 依赖。

maven 我不太熟悉,虽然有一个 maven-jlink-plugin ,但是貌似不能解决自动模块的问题,依赖没有完成模块化的库可能会产生问题,可以通过手动实现 badass jlink 插件背后的工作来解决。

jlink 可以用 --launcher 选项为程序生成一个启动器,这个启动器在 Linux 上是 bash 脚本,在 windows 上是 batch 脚本。

对于一般的命令行应用,自动生成的脚本完全够用,不过对于 GUI 应用,特别是在 windows 上,默认脚本的效果就差强人意了:

可以看到,因为是 bat 脚本,所以启动后会产生一个终端,任务管理器里应用也会显示到 OpenJDK Platform binary 下,当然这不是jlink的问题,不过确实让人感觉到这不是原生应用。我写了一个 launcher 通过用 JNI 调用实现简单的启动器解决了这个问题,外表接近原生应用,连 java.exe/javaw.exe 都不再需要(使用 jlink 时添加 --strip-native-commands 选项就能避免包含这些命令):

启动器部分已经开源,可以轻松的定制构建自己的 launcher:Java GUI launcher - ClassViewer​github.com

相关文章:

  • java 加载jar_java – 在运行时加载jar
  • java ant linux_linux下ant的安装
  • java获取数据库信息_java获取数据库的库、表、字段信息
  • java jpanel 布局管理器,JPanel和Java布局管理器
  • java 验证码识别 类库_iCaptcha
  • java调用wsdl证书错误_java调用.net web service服务,报证书错误
  • mysql 联表删除limit_MySQL联结多表更新和删除_mysql
  • mysql数据库备份总结_mysql中mysqlhotcopy备份数据库总结
  • java 反射 api_七分钟理解 Java 的反射 API
  • java 导入dbf文件_用java怎么实现批量导入dbf文件(从dbf文件导入到sqlserver2008中)到sqlserver2008...
  • md5算法 java_MD5算法[ java 实现]
  • java获取指定日期_Java 获取指定日期的前一周
  • java 读取 nextline_【Java】Scanner类nextInt后使用nextLine无法读取输入
  • java 监听所有异常_java – Spring JMS监听器即使在异常时也会确认
  • java生成xps文件_Java 将 Excel 转为PDF、图片、html、XPS、XML、CSV
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 2017-09-12 前端日报
  • Android开源项目规范总结
  • Java 23种设计模式 之单例模式 7种实现方式
  • Python连接Oracle
  • React16时代,该用什么姿势写 React ?
  • SegmentFault 2015 Top Rank
  • supervisor 永不挂掉的进程 安装以及使用
  • Web设计流程优化:网页效果图设计新思路
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 代理模式
  • 反思总结然后整装待发
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 事件委托的小应用
  • 跳前端坑前,先看看这个!!
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 用Visual Studio开发以太坊智能合约
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • # 透过事物看本质的能力怎么培养?
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • **PHP分步表单提交思路(分页表单提交)
  • .naturalWidth 和naturalHeight属性,
  • .NET 使用配置文件
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • @Bean有哪些属性
  • @EnableWebMvc介绍和使用详细demo
  • @JsonSerialize注解的使用
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • [100天算法】-每个元音包含偶数次的最长子字符串(day 53)
  • [1204 寻找子串位置] 解题报告
  • [android] 请求码和结果码的作用
  • [AX]AX2012 SSRS报表Drill through action