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

cnblogs 2024-09-20 08:09:10 阅读 80

javafx jlink 遇到的问题和处理

简介

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

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

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

一般 javafx:jilink 打包需要依赖的项目都是模块化的,然后使用插件 <code>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.class

javac -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.class

javac -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.class

javac -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,jlink 打包

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

<code><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 :声明服务接口的实现提供。

上一篇: 深入理解ConcurrentHashMap

下一篇: 佳芯小姐与猫

本文标签

maven    hutool    javafx    jlink   


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。