1、概述
通过mvn命令执行插件时报: because module java.base does not export sun.reflect.generics.reflectiveObjects to unnamed module 报错原因是, Java 9+的模块系统限制了未命名模块(unnamed module)对java.base模块内部类(sun.reflect包)的访问。 解决办法是 添加maven启动参数
"MAVEN_OPTS", "--add-exports java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED
2、--add-exports 和 --add-opens 作用
Java 9 引入的 --add-exports 和 --add-opens 主要用于解决模块化系统的访问控制问题,以下是两者的核心区别和作用:
2.1、 **--add-exports**
- 作用:将模块内的某个包导出给其他模块使用,允许其他模块在编译时和运行时访问该包中的公共类型和成员。
- 适用场景:跨模块的正常代码访问(非反射)。
- 语法:
--add-exports <源模块>/<包名>=<目标模块>
例如:--add-exports java.base/sun.security.x509=ALL-UNNAMED - 权限级别
仅开放公共(public)访问权限,其他模块可以像普通类库一样直接调用公共类和成员28。
2.2、 **--add-opens**
- 作用:打开模块内的某个包,允许其他模块在运行时通过反射访问该包中的所有类型和成员(包括非公共的)。
- 适用场景:需要深度反射的场景(如调用私有方法、修改私有字段)。
- 语法:
--add-opens <源模块>/<包名>=<目标模块>
例如:--add-opens java.base/sun.net.www.protocol.file=ALL-UNNAMED - 权限级别
开放完整的运行时反射权限(包括private、protected等成员)。
2.3、 核心区别对比
| 特性 | --add-exports | --add-opens |
|---|---|---|
| 适用范围 | 编译时和运行时访问公共成员 | 运行时反射访问所有成员 |
| 反射支持 | 不支持非公共成员 | 支持非公共成员 |
| 典型场景 | 跨模块公共 API 调用 | 第三方库/框架访问内部 API |
2.4、使用示例
1) 解决 IllegalAccessError(如搜索结果1的报错)
java --add-opens java.base/sun.net.www.protocol.file=ALL-UNNAMED -jar app.jar
2) 导出模块包给未命名模块(如单元测试)
java --add-exports moduleA/pkg=ALL-UNNAMED -jar app.jar