module java.base does not export sun.reflect.xxx to unnamed module

328 阅读2分钟

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
  • 权限级别
    开放完整的运行时反射权限(包括 privateprotected 等成员)。

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