Java 1.8升级至17后CachedRowSet实例化报错问题咨询
Java 1.8升级至17后CachedRowSet初始化报错解决方案
问题描述
将Java版本从1.8升级到17后,原代码CachedRowSet crs = new CachedRowSetImpl()需调整为CachedRowSet crs = RowSetProvider.newFactory().createCachedRowSet();,但运行单元测试时抛出错误:
java.util.MissingResourceException: Can't find bundle for base name com/sun/rowset/RowSetResourceBundle, locale en_US
堆栈信息如下:
at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045) at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1683) at java.base/java.util.ResourceBundle.getBundleFromModule(ResourceBundle.java:1603) at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:1014) at com.sun.rowset.JdbcRowSetResourceBundle.<init>(JdbcRowSetResourceBundle.java:105) at com.sun.rowset.JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(JdbcRowSetResourceBundle.java:124) at com.sun.rowset.CachedRowSetImpl.<init>(CachedRowSetImpl.java:360) at com.sun.rowset.RowSetFactoryImpl.createCachedRowSet(RowSetFactoryImpl.java:49)
原因分析
Java 9引入模块化系统后,对com.sun.rowset这类内部API的访问做了限制,RowSetResourceBundle属于Oracle JDK的内部资源包,在OpenJDK或模块化环境下无法直接访问,导致资源加载失败。
解决办法
方法一:添加JVM参数开放模块访问
在运行单元测试时添加以下JVM参数,允许应用访问com.sun.rowset相关模块:
--add-opens java.sql.rowset/com.sun.rowset=ALL-UNNAMED --add-opens java.sql.rowset/com.sun.rowset.internal=ALL-UNNAMED
如果使用Maven Surefire插件执行测试,可在pom.xml中配置参数:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine> --add-opens java.sql.rowset/com.sun.rowset=ALL-UNNAMED --add-opens java.sql.rowset/com.sun.rowset.internal=ALL-UNNAMED </argLine> </configuration> </plugin>
方法二:替换为第三方RowSet实现
使用开源库的RowSet实现替代JDK自带的CachedRowSetImpl,例如Apache Commons DbUtils:
- 添加Maven依赖:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> <scope>test</scope> </dependency>
- 修改代码初始化逻辑:
CachedRowSet crs = new org.apache.commons.dbutils.wrappers.CachedRowSetWrapper();
内容的提问来源于stack exchange,提问作者Senarath
相关产品推荐
相关产品推荐

