Mac系统为何出现java.lang.reflect.InaccessibleObjectException异常?
Java单项目构建抛出DirectByteBuffer私有构造访问异常解决方案
错误特征
- 多项目并行开发环境下仅单个项目构建失败,其余项目构建流程正常
- 同环境下该项目此前已稳定构建多日,无配置变更时突然报错
- 核心错误栈信息为:
java.lang.reflect.InaccessibleObjectException: Unable to make private java.nio.DirectByteBuffer(long,int) accessible
根因定位
这个报错由Java 9引入的JPMS(Java平台模块系统)强封装规则触发,仅单项目报错的常见触发条件如下:
- 该项目依赖的某个第三方组件未适配JPMS规则,内部通过反射直接访问
java.nio.DirectByteBuffer的私有构造方法 - 近期该项目更新了依赖版本、或全局构建JDK版本升级到16及以上(JDK 16进一步收紧了内部API反射访问的权限限制)
- 该项目的构建JVM参数近期被修改,移除了此前存在的内部API访问豁免配置
修复方案
快速恢复方案
在对应项目的构建/运行JVM参数中添加开放权限配置即可临时解决:
- Maven项目:在项目根目录的
.mvn/jvm.config文件中添加如下参数,或在pom.xml的maven-compiler-plugin配置的jvmArgs节点添加该参数:--add-opens java.base/java.nio=ALL-UNNAMED - Gradle项目:在
gradle.properties文件中添加配置:org.gradle.jvmargs=--add-opens java.base/java.nio=ALL-UNNAMED - Jar包直接运行时,在启动命令中添加参数:
java --add-opens java.base/java.nio=ALL-UNNAMED -jar <your-project.jar>
若后续还出现其他JDK内部类的同类访问报错,可参照上述格式调整
--add-opens后的模块路径即可。
长期稳定方案
临时的权限开放仅做应急使用,建议通过以下操作彻底解决问题:
- 排查该项目所有依赖,定位到内部反射调用DirectByteBuffer私有构造的组件,将其升级到适配Java 9+模块规则的版本:
- 若依赖Netty,升级到4.1.68.Final及以上版本
- 若为自研工具类依赖,将反射构造DirectByteBuffer的逻辑替换为JDK公开API
ByteBuffer.allocateDirect(int capacity)实现
- 确认项目全局构建JDK版本与生产运行版本保持一致,避免跨版本构建引入的兼容性问题
内容的提问来源于stack exchange,提问作者offby1
相关产品推荐
相关产品推荐

