Java8迁移至Java10获取ResourceBundle遇IllegalAccessException求助
Java 10迁移:ResourceBundle访问内部com.sun.swing包的IllegalAccessException解决办法
我之前也遇到过类似的模块化迁移坑,你的问题核心是Java 9+模块系统对内部私有API的严格访问限制,即便加了--add-opens和--add-exports,也可能因为参数使用细节或加载机制变化导致不生效。下面一步步帮你解决:
1. 先确认JVM参数的位置是否正确
这是最容易被忽略的点:JVM参数必须放在java命令之后、你的应用jar/主类之前。如果把参数写在jar文件后面,它们会被当成应用的程序参数,而非JVM参数,自然不会生效。
正确的启动命令示例:
java --add-opens=java.desktop/com.sun.swing.internal.plaf.metal.resources=ALL-UNNAMED \ --add-exports=java.desktop/com.sun.swing.internal.plaf.metal.resources=ALL-UNNAMED \ -jar your-application.jar
2. 调整ResourceBundle的加载方式
模块化环境下默认类加载器的行为有变化,尝试显式指定当前类的类加载器来加载资源包,确保能正确定位到java.desktop模块中的内部类:
// 替换原来的代码,显式传入当前类的类加载器 ResourceBundle bundle1 = ResourceBundle.getBundle( "com.sun.swing.internal.plaf.metal.resources.metal", Locale.getDefault(), getClass().getClassLoader() );
3. 长远解决方案:避免依赖内部API
需要提醒的是,com.sun.*开头的包都是Oracle/Sun的内部私有API,官方不保证跨版本兼容性,后续Java版本可能会进一步限制甚至移除这些API。更稳妥的做法是:
- 提取你需要的Metal主题资源键值对,放到自己的资源文件中(比如
metal_custom.properties) - 使用Swing公开API获取主题资源,比如通过
UIManager.getDefaults()访问MetalLookAndFeel的默认配置
为什么原参数可能不生效?
你添加的--add-exports是让java.desktop模块把指定包的public类导出给未命名模块,--add-opens则是开放包的所有访问权限(包括非public类和反射访问)。但如果参数位置错误,这些配置根本不会被JVM读取,自然无法解决IllegalAccessException。
内容的提问来源于stack exchange,提问作者baalus
相关产品推荐
相关产品推荐

