我希望有人可以对这个奇怪的问题有所了解
我的安卓设备上有一个 iJetty WebApp。我们有能力在用户关闭他们的码头服务器但 Dalvik 虚拟机在线后清除我们的 H2 DB。
在以下情况后出现异常:1. 启动服务器 2. 登录系统(如果 H2 数据库不存在,则创建 H2 数据库,以及建立连接的位置) 3. 停止服务器(这会断开所有连接到数据库) 4. 从应用程序中删除 h2 数据库(这会删除 h2 db 文件) 5. 启动应用程序 6. 登录到系统(如果 H2 数据库不存在,则创建连接)
当我这样做两次时,一切正常。但是当第三次我得到这个异常时:
java.lang.ExceptionInInitializerError
.
.
.
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
at java.sql.DriverManager.getDrivers(DriverManager.java:258)
at org.apache.commons.dbcp.BasicDataSource.<clinit>(BasicDataSource.java:57)
... 41 more
关于问题的说明:
- 我们根本不会在 Spring 中初始化实际的数据源。我们在 Java 中调用:
BasicDataSource dataSource = new BasicDataSource();
每当需要建立新连接时。 - 当 Jetty 服务器出现故障时,我尝试发出 SQL 命令“SHUTDOWN”,但这并没有改变任何东西。
- 查看 DriverManager 的代码,我很困惑异常是如何发生的。他们对正在迭代的数组列表进行同步。
- 我最初在 H2 论坛上发布了这个问题,以检查他们是否注意到它。我不认为它是 H2 特有的东西。(https://groups.google.com/forum/#!topic/h2-database/OiKNgnYjOSM)
任何想法将不胜感激
更新 下面是对 API 17 的 Andorid DriverManager.java 的调用(它也发生在 18 中)。如果我能找到他们回购的链接,我会发布
/**
* Returns an {@code Enumeration} that contains all of the loaded JDBC
* drivers that the current caller can access.
*
* @return An {@code Enumeration} containing all the currently loaded JDBC
* {@code Drivers}.
*/
public static Enumeration<Driver> getDrivers() {
/*
* Synchronize to avoid clashes with additions and removals of drivers
* in the DriverSet
*/
ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
synchronized (theDrivers) {
ArrayList<Driver> result = new ArrayList<Driver>();
for (Driver driver : theDrivers) { // THIS IS THE OFFENDING LINE
if (DriverManager.isClassFromClassLoader(driver, callerClassLoader)) {
result.add(driver);
}
}
return Collections.enumeration(result);
}
}