jmod 不能打包“模块化变量资源”,因其不存在;jmod 是仅用于编译/链接阶段的模块化资源打包工具,支持 class、native、conf、bin 等混合资源,供 jlink 构建最小可信运行时镜像,不参与运行时加载。

不能用 jmod 打包“模块化变量资源”,因为 Java 中没有“模块化变量资源”这个概念;jmod 的核心作用是打包模块化资源集合(如类、原生库、配置、头文件等),用于编译和链接阶段,而非运行时分发——它本身不提供运行时安全性,但能通过结构化封装与哈希绑定间接提升分发可控性。
明确 jmod 的定位与边界
JMOD 是一种仅限编译/链接阶段使用的传输格式,不是运行时加载单元。JVM 明确拒绝通过 --module-path 加载 .jmod 文件,尝试会报错:Error occurred during initialization of VM java.lang.module.ResolutionException: JMOD files not supported。
这意味着:
- JMOD 不替代 JAR 或 modular JAR,不用于常规部署或 Maven 发布
- 它的价值在于为
jlink构建定制运行时镜像提供输入,或为含 native 库的模块提供统一打包载体 - 所谓“提升分发安全性”,实则是通过内容固化、依赖哈希绑定、路径隔离等方式增强构建链路的可验证性,而非加密或防篡改
打包混合资源:class + native + conf + bin
JMOD 支持将多种类型资源归入同一模块容器,目录结构固定为:
-
classes/:必须包含module-info.class和所有编译后类 -
native/:存放平台相关动态库(如libfoo.dll、libfoo.so) -
conf/:放置默认配置文件(如logback.xml) -
bin/:含可执行脚本(如启动 shell/bat 脚本)
打包命令示例(假设模块名 com.example.crypto,类在 mods/com.example.crypto 目录):
--class-path mods/com.example.crypto \
--include-native-libs libs/native/windows-x64 \
--config-dir conf \
--bin-dir scripts \
com.example.crypto.jmod
用哈希绑定控制模块依赖可信性
通过 jmod hash 或 --hash-modules,可在模块描述符中记录允许依赖该模块的其他模块的哈希值,实现“白名单式导出”。例如:
这会使 com.example.crypto 仅允许被 java.base 和 com.example.util(及其对应哈希匹配版本)使用其 exports 的包。运行时若解析到哈希不匹配的依赖模块,JVM 将拒绝加载并报错。这是一种轻量级的构建期策略控制,适用于内部模块生态治理。
配合 jlink 构建最小可信运行时
JMOD 的真正安全价值体现在与 jlink 协同使用时:
- 所有 JDK 模块(如
java.base.jmod)都以 JMOD 形式提供,jlink只读取 JMOD,不接受 JAR - 自定义模块打成 JMOD 后,可参与
jlink链接,生成不含冗余类、无未授权反射入口、无调试符号的精简镜像 - 镜像中每个模块的哈希可校验,整个运行时二进制具备强一致性,降低供应链投毒风险(对比直接分发含大量第三方 JAR 的 fat jar)
典型流程:
jlink \--module-path jmods/:my-modules/ \
--add-modules com.example.crypto,java.base \
--output my-runtime










