Unable to make field private final java.lang.String java.io.File.path accessible: module java.base
问题猫头虎 在使用 Java 9 及以上版本时,模块化(Module System)带来的反射限制常会导致如下异常:
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not “opens java.io” to unnamed module @...
本教程将结合 JDK 8、JDK 11、JDK 17、JDK 21 环境,分步详解该问题的成因及解决方法,帮助你快速上手处理模块化反射访问失败的场景。
java.io.File
的私有字段(如 path
)时,会因未打开相应包而抛出 InaccessibleObjectException
。JDK 版本 | 模块化支持 | 是否抛出异常 |
---|---|---|
JDK 8 | 否 | 不会抛出 |
JDK 11 | 是 | 会抛出 InaccessibleObjectException |
JDK 17 | 是 | 同 JDK 11 |
JDK 21 | 是 | 同 JDK 11 |
java.base/java.io
包至调用代码所在模块/unnamed module。
module-info.java
声明。对于 JDK ≥ 9,推荐使用 JVM 参数 方式,命令行启动时添加:
# 打开 java.base 模块中的 java.io 包给所有 unnamed module
java --add-opens java.base/java.io=ALL-UNNAMED -jar your-app.jar
打开 Run/Debug Configurations。
在 VM options 中加入:
--add-opens=java.base/java.io=ALL-UNNAMED
保存并运行。
在 pom.xml
的 <plugin>
配置里,针对 maven-surefire-plugin
和 maven-compiler-plugin
添加:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>--add-opens java.base/java.io=ALL-UNNAMED</argLine>
</configuration>
</plugin>
tasks.withType(Test) {
jvmArgs += "--add-opens=java.base/java.io=ALL-UNNAMED"
}
如果你的项目本身采用模块化(即存在 module-info.java
),可以在项目模块的声明中添加:
// module-info.java
module your.module.name {
// 允许本模块使用反射访问 java.io 包
opens java.io to your.module.name;
// 其他依赖声明
requires java.base;
}
⚠️ 注意
opens
只能对自定义模块生效,对 java.base
这样的 JDK 模块,仍需 JVM 参数 --add-opens
。opens
形式适用于拆分自身项目模块内各包的进出权限管理,不是针对 JDK 模块的开放。以下示例演示了无额外参数和加了 --add-opens
参数时的运行结果对比。
import java.lang.reflect.Field;
import java.io.File;
public class ReflectTest {
public static void main(String[] args) throws Exception {
Field pathField = File.class.getDeclaredField("path");
pathField.setAccessible(true); // 这里会触发 InaccessibleObjectException
File f = new File("test.txt");
System.out.println(pathField.get(f));
}
}
不带参数运行(JDK 11+)
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module @...
带参数运行
java --add-opens java.base/java.io=ALL-UNNAMED ReflectTest
# 输出 "test.txt"
--illegal-access=permit
?
A:该参数只在 JDK 9~15 默认允许非法访问,JDK 16+ 已移除,不建议依赖。module java.base does not “opens java.lang”
,同理添加 --add-opens java.base/java.lang=ALL-UNNAMED
。--add-opens java.base/java.io=ALL-UNNAMED
module-info.java
中使用 opens
(仅限自定义模块)。
通过本教程,你已掌握了在不同 JDK 版本下,快速定位并修复 “Unable to make field … accessible” 异常的实战方法。祝你编码顺利,项目无忧!
✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️✍️
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有