模块描述符(module-info.java)是模块化系统信任起点,需配合编译约束、签名机制与运行时校验保障变量库交付完整性,包括精确导出控制、版本签名、服务声明、哈希注入及静态断言。
模块描述符(module-info.java)本身不是校验工具,不能直接用于“完整性校验”,但它构成模块化系统的信任起点——通过显式声明依赖、导出包和使用服务,为后续可验证的构建与交付流程打下基础。真正保障变量库(如配置项、常量集合、参数定义等)交付完整性,需将模块描述符作为策略锚点,配合编译期约束、签名机制与运行时校验协同实现。
明确模块边界与导出控制
变量库若以模块形式发布,必须在 module-info.java 中精确声明:
- 仅 导出供客户使用的公共变量类或接口包(如
exports com.example.vars.public;),隐藏内部实现类、测试常量或调试开关 - 用 requires static 声明仅编译期需要的依赖(如注解处理器),避免客户运行时意外加载无关模块
- 对敏感变量模块添加 requires transitive 并配套
opens(如需反射访问),但须同步启用 JVM 参数--add-opens进行显式授权,防止隐式绕过
绑定变量定义与模块版本签名
变量库的完整性不在于“内容不变”,而在于“来源可信、版本可控”:
- 在构建阶段用
jarsigner对 JAR 签名,并将公钥指纹写入module-info.java注释区(如// SIG: SHA-256=abc123...),供客户脚本自动比对 - 利用
ModuleDescriptor.Version在模块描述符中硬编码语义化版本(如version "2.1.0-secure"),禁止客户加载低于指定小版本的库(通过自定义SecurityManager或模块解析器拦截) - 若变量含加密密钥或证书路径,应在
module-info.java中用uses声明所需的服务类型(如uses com.example.crypto.KeyProvider;),强制客户注入已校验的实现
构建时注入校验逻辑与元数据
借助注解处理器或构建插件,在编译阶段将变量库的哈希摘要、字段签名或校验规则注入模块属性:
- 用
javac -processor扫描所有public static final变量,生成META-INF/MODULE-VARS.SHA256文件并打包进模块 JAR - 在
module-info.java中添加自定义属性:module com.example.vars { requires java.base; provides "vars.checksum" with "sha256:fe8a..."; } - 客户启动时调用
Module.getDescriptor().rawAttributes()读取该值,并比对实际变量类字节码的 SHA-256,失败则抛出SecurityException
运行时轻量级一致性断言
模块描述符可触发初始化期校验,无需额外框架:
- 在模块静态块中编写断言逻辑(如
static { assert Constants.API_TIMEOUT > 0 : "API timeout invalid"; }),JVM 加载时即执行 - 结合
java.lang.System.Logger输出校验结果,并设置jdk.module.system.logger.level=DEBUG供客户审计 - 对关键变量(如加密算法名称、端口白名单)使用
@Deprecated(forRemoval = true)标记废弃项,并在模块描述符注释中注明替代方案与截止版本

















