Subject ConcurrentModificationException in FBManagedConnection.disassociateConnections - possible bug?
Author Pavel Palát
Hello,

I'm currently working with firebird on Sun Application Server Platform
Edition 9.0, Jaybird 2.1.0rc1 and I'm sometimes getting this error:

java.util.ConcurrentModificationException:
java.util.AbstractList$Itr.checkForComodification(AbstractList.java:374)
java.util.AbstractList$Itr.next(AbstractList.java:345)
org.firebirdsql.jca.FBManagedConnection.disassociateConnections(FBManagedConnection.java:422)
org.firebirdsql.jca.FBManagedConnection.cleanup(FBManagedConnection.java:404)
com.sun.enterprise.resource.AbstractConnectorAllocator.closeUserConnection(AbstractConnectorAllocator.java:157)
com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.componentDestroyed(J2EETransactionManagerImpl.java:677)
com.sun.web.server.J2EEInstanceListener.handleAfterEvent(J2EEInstanceListener.java:364)
com.sun.web.server.J2EEInstanceListener.instanceEvent(J2EEInstanceListener.java:103)
org.apache.catalina.util.InstanceSupport.fireInstanceEvent(InstanceSupport.java:435)
com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:414)
com.sun.faces.application.ViewHandlerImpl.executePageToBuildView(ViewHandlerImpl.java:455)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:139)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:266)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:159)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)


Looking in sources of disassociateConnections, there is:

for (Iterator i = connectionHandles.iterator(); i.hasNext();) {
AbstractConnection connection = (AbstractConnection) i.next();

try {
connection.close();
} catch(SQLException sqlex) {
if (ex == null)
ex = new FBResourceException(sqlex);
else

((SQLException)ex.getLinkedException()).setNextException(sqlex);
}
}

so it clearly isn't synchronized (and this connectionHandles variable is
accessed from other methods.


My code basicaly works in two ways - first are EJB, where the datasource
is injected from resource injection, seconds components use JNDI lookup:

public static Connection getConnection() {
try {
InitialContext ctx=new InitialContext();
DataSource ds=(DataSource)ctx.lookup("viaportal");
return ds.getConnection();
} catch (NamingException e) {
throw new RuntimeException(e);
} catch (SQLException e ){
throw new RuntimeException(e);
}
}

public static void returnConnection(Connection con) {
try {
con.close();
} catch (Exception e) { //make sure we don't throw any exceptions'
System.err.println(e);
e.printStackTrace();
}
}

so basically I do a lot of connection allocation and deallocation from
ConnectionPool so I think it can trigger this race condition. But I'm no
expert on JCA internals.

Thanks for any suggestion

Pavel Palat