javafx jlink 遇到的非模块化的依赖打包报错“模块异常”的问题和处理

news/2024/11/5 11:41:31/文章来源:https://www.cnblogs.com/monsterbude/p/18421622

简介

javafx:jlink 是 javafx-maven-plugin 插件中的一个目标,用于创建一个自包含的 JavaFX 应用程序运行时映像。这个目标利用 Java 的 jlink 工具来生成一个包含应用程序及其所有依赖的定制化运行时映像,从而简化部署和分发。

  • 创建自包含运行时:通过 jlink 创建一个定制的 Java 运行时环境(JRE),只包含应用程序所需的模块和依赖。这可以减少最终部署包的大小。
  • 模块化:与传统的 JRE 相比,生成的运行时映像是模块化的,只包含你的应用程序实际需要的 Java 模块。
  • 简化部署:可以将生成的运行时映像作为最终用户的运行环境,减少对系统环境的依赖。

打包遇到非模块依赖时的处理

一般 javafx:jilink 打包需要依赖的项目都是模块化的,然后使用插件 javafx-maven-plugin进行 javafx:jlink 一键打包

<plugin><groupId>org.openjfx</groupId><artifactId>javafx-maven-plugin</artifactId><version>0.0.8</version><configuration><stripDebug>true</stripDebug><compress>2</compress><noHeaderFiles>true</noHeaderFiles><noManPages>true</noManPages><launcher>FxExample</launcher><jlinkImageName>FxExample</jlinkImageName><jlinkZipName>FxExampleZip</jlinkZipName><mainClass>com.xxx.xxx.FxExampleApp</mainClass></configuration>
</plugin>

但是总会有那种没有模块化的依赖,比如说 hutool 包,默认是没有模块化的,这个时候就需要自行补全这个模块化的信息
首先在仓库中找到所有依赖的没有模块化的包,我这里用 hutool 举例子
我的项目依赖了(其中 setting 依赖了 log 和 core)

hutool-core-5.8.29.jar
hutool-json-5.8.29.jar
hutool-setting-5.8.29.jar
hutool-log-5.8.29.jar

准备临时编译目录

新建一个临时的空的 maven 项目,或者一个空文件夹,我这里为了方便,使用的空的 maven 项目
将依赖的 jar 复制到项目中,从控制台 cd 到项目路径

在项目路径下面为每个 jar 生成 module-info.java

# 使用jdk自带的工具扫描自动生成module-info.java
jdeps --ignore-missing-deps --generate-module-info . *.jar

日志

Warning: --ignore-missing-deps specified. Missing dependencies from cn.hutool.setting are ignored
writing to .\cn.hutool.setting\module-info.java
writing to .\cn.hutool.json\module-info.java
Warning: --ignore-missing-deps specified. Missing dependencies from cn.hutool.core are ignored
writing to .\cn.hutool.core\module-info.java

生成的内容比如 cn.hutool.core/module-info.java
这里建议直接将整个 module open 了,方便反射机制的调用,还有如果遇到需要 uses 的接口,也需要加到模块信息中,不然后续打完包运行过程遇到对应的类,还是会报模块没有配置某个类的 uses 信息,以下是我根据我的情况修改了内容的 module-info

open module cn.hutool.core {requires java.management;requires transitive java.compiler;requires transitive java.datatransfer;requires transitive java.desktop;requires transitive java.naming;requires transitive java.sql;requires transitive java.xml;uses cn.hutool.core.convert.Converter;uses cn.hutool.core.convert.TypeConverter;exports cn.hutool.core.annotation.scanner;exports cn.hutool.core.annotation;exports cn.hutool.core.bean.copier.provider;exports cn.hutool.core.bean.copier;exports cn.hutool.core.bean;exports cn.hutool.core.builder;exports cn.hutool.core.clone;exports cn.hutool.core.codec;exports cn.hutool.core.collection;exports cn.hutool.core.comparator;exports cn.hutool.core.compiler;exports cn.hutool.core.compress;exports cn.hutool.core.convert.impl;exports cn.hutool.core.convert;exports cn.hutool.core.date.chinese;exports cn.hutool.core.date.format;exports cn.hutool.core.date;exports cn.hutool.core.exceptions;exports cn.hutool.core.getter;exports cn.hutool.core.img.gif;exports cn.hutool.core.img;exports cn.hutool.core.io.checksum.crc16;exports cn.hutool.core.io.checksum;exports cn.hutool.core.io.copy;exports cn.hutool.core.io.file.visitor;exports cn.hutool.core.io.file;exports cn.hutool.core.io.resource;exports cn.hutool.core.io.unit;exports cn.hutool.core.io.watch.watchers;exports cn.hutool.core.io.watch;exports cn.hutool.core.io;exports cn.hutool.core.lang.ansi;exports cn.hutool.core.lang.caller;exports cn.hutool.core.lang.copier;exports cn.hutool.core.lang.func;exports cn.hutool.core.lang.generator;exports cn.hutool.core.lang.hash;exports cn.hutool.core.lang.id;exports cn.hutool.core.lang.intern;exports cn.hutool.core.lang.loader;exports cn.hutool.core.lang.mutable;exports cn.hutool.core.lang.reflect;exports cn.hutool.core.lang.tree.parser;exports cn.hutool.core.lang.tree;exports cn.hutool.core.lang;exports cn.hutool.core.map.multi;exports cn.hutool.core.map;exports cn.hutool.core.math;exports cn.hutool.core.net.multipart;exports cn.hutool.core.net.url;exports cn.hutool.core.net;exports cn.hutool.core.stream;exports cn.hutool.core.swing.clipboard;exports cn.hutool.core.swing;exports cn.hutool.core.text.csv;exports cn.hutool.core.text.escape;exports cn.hutool.core.text.finder;exports cn.hutool.core.text.replacer;exports cn.hutool.core.text.split;exports cn.hutool.core.text;exports cn.hutool.core.thread.lock;exports cn.hutool.core.thread.threadlocal;exports cn.hutool.core.thread;exports cn.hutool.core.util;
}

编译 module-info.java 为 module-info.class 并且注入 module-info.class 到 jar

这里需要注意一下编译的顺序,对于 hutool-core 模块来说,它没有其他的依赖模块,可以先直接编译这个模块

# 生成module-info.class
javac --patch-module cn.hutool.core=hutool-core-5.8.29.jar cn.hutool.core/module-info.java
# 注入module-info.class到jar
jar uf hutool-core-5.8.29.jar -C cn.hutool.core module-info.class

其他模块编译和注入(增加-p 来引入依赖的模块)

javac --patch-module cn.hutool.core=hutool-core-5.8.29.jar cn.hutool.core/module-info.java
jar uf hutool-core-5.8.29.jar -C cn.hutool.core module-info.classjavac -p hutool-core-5.8.29.jar --patch-module cn.hutool.json=hutool-json-5.8.29.jar cn.hutool.json/module-info.java
jar uf hutool-json-5.8.29.jar -C cn.hutool.json module-info.classjavac -p hutool-core-5.8.29.jar --patch-module cn.hutool.log=hutool-log-5.8.29.jar cn.hutool.log/module-info.java
jar uf hutool-log-5.8.29.jar -C cn.hutool.log module-info.classjavac -p "hutool-core-5.8.29.jar;hutool-log-5.8.29.jar" --patch-module cn.hutool.setting=hutool-setting-5.8.29.jar cn.hutool.setting/module-info.java
jar uf hutool-setting-5.8.29.jar -C cn.hutool.setting module-info.class

然后将处理好之后的 jars 复制到原项目 libs 目录,修改 maven 依赖,如果 idea 报红,则将 libs 添加到项目的 library

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.8.29</version><scope>system</scope><systemPath>${project.basedir}/libs/hutool-core-5.8.29.jar</systemPath>
</dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-setting</artifactId><version>5.8.29</version><scope>system</scope><systemPath>${project.basedir}/libs/hutool-setting-5.8.29.jar</systemPath>
</dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-json</artifactId><version>5.8.29</version><scope>system</scope><systemPath>${project.basedir}/libs/hutool-json-5.8.29.jar</systemPath>
</dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-log</artifactId><version>5.8.29</version><scope>system</scope><systemPath>${project.basedir}/libs/hutool-log-5.8.29.jar</systemPath>
</dependency>

然后执行 javafx:jlink,这时就能正常打包代码了

module-info 基础知识补充

  • module :声明模块及其名称。
  • open module :声明整个模块允许反射访问。
  • requires :声明对其他模块的依赖。
  • requires transitive :声明传递性依赖。
  • exports :公开包,使得其他模块可以访问。
  • opens :开放包,允许反射访问。
  • opens to :开放包,仅对指定模块允许反射访问。
  • uses :声明对服务接口的依赖。
  • provides ... with :声明服务接口的实现提供。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/800183.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

The minimum required version for Powerlevel10k is 5.1

目录一、背景二、原因三、解决1、安装 ZSH 最新版本2、效果3、下载了还是显示 ZSH 版本为 5.0.2 怎么办 一、背景 安装 ZSH 主题 Powerlevel10k 时报错:You are using ZSH version 5.0.2. The minimum required version for Powerlevel10k is 5.1. Type echo $ZSH_VERSION to …

Python pycryptodome类库使用学习总结

AES数据加解密 以下代码生成一个新的AES-128密钥,并将一段数据加密到一个文件中。我们使用 CTR 模式(这是一种 经典操作模式, 简单但不再推荐)。 仅使用CTR,接收者无法检测到密文(即加密数据)在传输过程中是否被修改。为了应对这种风险,例中还附加了一个MAC身份验证标签…

电脑设置系统不自动更新

1、win + R 2、计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\StateVariables 3、右边空白处右击 -> 新建 -> DWORD值,命名为FlightSettingsMaxPauseDays,点击基数选择十进制,数值设置为9999(表示不更新的天数)

同花顺--涨停板改变颜色

复制以下代码 IF(C>=REF(C,1)*1.095 AND C=H) RETURN "涨停"; 然后进行操作: 1、打开同花顺软件,右击K线,单击修改K线2、光标挪到代码首行行首,回车换行3、粘贴一下4、点击设置标志5、命名为涨停,选颜色,填充打勾6、点击确定

关于零值和nil

1. 零值 零值是指当你声明变量(分配内存)并未显式初始化时,始终为你的变量自动设置一个默认初始值的策略。 对于值类型:布尔类型为 false, 数值类型为 0,字符串为 "",数组和结构会递归初始化其元素或字段,即其初始值取决于元素或字段。 对于引用类型: 均为 n…

利用AutoGpt将任何模型支持o1模型的推理实现

利用AutoGpt将任何模型支持o1模型的推理实现 相信大家都对于OpenAI最新出的o1模型都非常关注,它已经能通过推理让回复的效果更加理想, 但是目前o1的限制太大,而且使用o1至少也是需要购买OpenAI官方的会员价格也在20美刀(好贵!!),于是乎社区出现非常多相似的实现,通过更…

C语言类型与强制类型转换

目录类型关键字sizeof如何理解强制类型转化不同类型的0null字符设备(补充) char有有符号和无符号两种类型,字符是无符号类型.(补充) getchar的返回值为什么是int键盘输入的内容,以及往显示器中打印的内容,都是字符 --> 键盘/显示器称为字符设备 类型C语言为何有类型? 让我们…

如何在 ASP.NET Core Web API 方法执行前后 “偷偷“ 作一些 “坏“ 事?初识 ActionFilterAttribute

ActionFilterAttribute 是一种作用于控制器 Action 方法的特性(Attribute),通过它,你可以在操作执行前后、异常处理时等不同的阶段插入自定义逻辑。 比如在执行操作方法之前修改请求参数、记录日志、进行权限验证等操作,在执行操作方法之后发送邮件、同步数据等等。 本文主…

访问Github卡顿甚至进不去的解决办法(适用于Windows)

本文使用Watt Tookit(原Steam++)解决了Github在国内访问速度卡顿甚至无反应的问题,通过NDM和镜像网站实现Github大文件高速下载。本文首发自个人博客:点我查看 一、前言 Github 是全球知名的开源宝库,但是对国内用户并不友好。当我们在浏览器中输入www.github.com时,如果…

看看mysql干的恶心事

如图: 本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/18421514

LoRaWAN网关价格干穿地板了

曾经LoRaWAN网关要上万块钱一台,后来卷到千把块钱,现在可以卷到500以内,还支持4G/ETH/WIFI,应该也是没谁了。 先上图片1.1 产品特点 ◆ 高性能嵌入式硬件平台 ◆ 使用工业级 Cat.1 4G 模块 ◆ 宽压输入 DC 9~28V,工业级稳定性 ◆ 群脉冲:电源2kV,通讯线4kV ◆ 湿度范围…

认知神经科学分析指标——图论指标之全局集群系数

图论指标在认知神经科学或脑科学的研究中,通常作为研究脑网络表现的描述性指标之一,而图论指标从全局性来分可以分为:节点指标和全局指标,而根据描述脑网络整合性表现又可分为:整合指标和分离指标。 该随笔主要涉及图论指标中全局指标及整合指标的全局集群系数,英文全称为…