Subject | ConcurrentModificationException in FBManagedConnection.disassociateConnections - possible bug? |
---|---|
Author | Pavel Palát |
Post date | 2006-10-29T15:23:57Z |
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
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