JDK9+模块系统是什么?JavaFx在JDK9+打包时遇到: 自动模块不能用于来自 file:///xxxxx.jar 的 jlink: xxxxx的解决方案

问题原因

这是在JavaFx在JDK9+情况下的一个问题,原因是JDK9启用了模块化系统,旨在帮助开发人员更好地管理大型代码库的依赖关系,并提高应用程序的安全性和可维护性,但是我们依赖的很多JAR包可能并没有适配JDK9,所以当我们在JDK9的主项目中尝试去依赖一个没有启用模块化系统的包时就会遇到这个问题,自动模块即没有启用模块化系统。

概念了解

1、模块声明

module-info.java文件使用module关键字声明一个模块。模块名称应该是全局唯一的,通常使用反向域名约定。

module com.example.myapp {
    // 模块的内容
}

2、requires

requires语句声明该模块依赖的其他模块。它告诉编译器和运行时环境,这个模块需要其他模块才能正常工作。

module com.example.myapp {
    requires javafx.controls;
    requires org.json;
}

3、 exports

exports语句声明该模块公开的包。只有被exports声明的包才能被其他模块访问。

module com.example.myapp {
    requires javafx.controls;
    requires org.json;
    exports com.example.myapp;
}

4、 opens

opens语句声明该模块中的包可以被反射访问。它通常用于JavaFX和依赖反射的框架。

module com.example.myapp {
    requires javafx.controls;
    requires org.json;
    exports com.example.myapp;
    opens com.example.myapp to javafx.fxml;
}

5、 provides 和 uses

provides语句用于声明该模块提供某个服务的实现,而uses语句用于声明该模块使用某个服务。

module com.example.myapp {
    requires javafx.controls;
    requires org.json;
    exports com.example.myapp;
    uses com.example.service.MyService;
    provides com.example.service.MyService with com.example.myapp.MyServiceImpl;
}

问题解决

我们需要把我们的自动模块经过重新打包生成module-info.java这个文件,并让它打入JAR包内。

1、生成依赖模块信息

jdeps是jdk自带的依赖分析工具,这个针对简单的依赖浅的JAR很有效,如果说依赖树很深的情况下,建议先排查一下依赖,从最底层的开始操作,但是我这里的JAR包无其他依赖,所以直接操作就行了, 其中的

  • –ignore-missing-deps:忽略错误依赖
  • –generate-module-info: 生成模块信息文件module-info.java,后面是模块信c息文件输出位置
jdeps --ignore-missing-deps --generate-module-info . json-20231013.jar

执行完成之后就会看到生成一个Module-info.java的文件,我们需要把它再编译成class,然后再打入jar里面

2、编译module-info.java

  • –patch-module指的是用于将一个或多个JAR文件或目录添加到指定模块的编译路径中,是key=value形式的,表示你要将json-20231013.jar中的内容作为org.json模块的一部分。
  • org.json/module-info.java 这是你要编译的module-info.java文件的路径。此文件定义了org.json模块的模块描述符。
  • p 参数(可选),如果你的JAR需要依赖其他jar,比如json,那么你就需要加上-p参数指定jar包,这样打出来的module-info.java才会包含requires org.json,如果代码里面依赖了json,然而你却没有在module-info.java中requires,那么打出来的JAR执行就会报错
javac --patch-module org.json=json-20231013.jar org.json/module-info.java

3、将module-info.class注入到JAR中

这个操作会直接替换掉原有的JAR包,建议做好备份

  • u 这个选项用于更新现有的JAR文件,即在已有的JAR文件中添加或替换文件。
  • f 这个选项指定JAR文件的名称,后面跟着JAR文件的路径。
  • json-20231013.jar 这是要更新的JAR文件的名称。
  • -C 这个选项用于改变目录。-C dir选项告诉jar工具在切换到dir目录后再执行后续的文件操作。这个选项对于处理目录结构很有用。
  • module-info.class 这是要添加到JAR文件中的具体文件,即模块描述符的编译类文件。
jar uf json-20231013.jar -C org.json module-info.class

操作完成之后就可以打开JAR包看到了
在这里插入图片描述

这时候我们再执行打包,就可以打包成功了。

在这里插入图片描述

版权所有:XuanRan
未经书面授权,禁止转载

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值