Subject | Re: [Firebird-Java] ConcurrentModificationException in FBManagedConnection.disassociateConnections - possible bug? |
---|---|
Author | David Jencks |
Post date | 2006-10-29T16:50:10Z |
I very much doubt this is due to a race condition but rather that
this is the first time a managed connection with 2 handles has been
cleaned up.
I suspect code like:
public void dissociateConnections() throws ResourceException {
while (!handles.isEmpty()) {
DissociatableConnectionHandle handle =
(DissociatableConnectionHandle) handles.removeFirst();
handle.setAssociation(null);
}
}
will work better. (The above code is from a j2ca 1.5 adapter that
implements the "avoid connection handle leaks" feature I mentioned
recently).
I think what is happening is that connection.close() is modifying the
list of connections, and thus next() is detecting the change and
throwing the CME.
At the moment I don't understand why the sun code is calling cleanup
on a managed connection with any handles, so there may be other
problems here as well.
thanks
david jencks
this is the first time a managed connection with 2 handles has been
cleaned up.
I suspect code like:
public void dissociateConnections() throws ResourceException {
while (!handles.isEmpty()) {
DissociatableConnectionHandle handle =
(DissociatableConnectionHandle) handles.removeFirst();
handle.setAssociation(null);
}
}
will work better. (The above code is from a j2ca 1.5 adapter that
implements the "avoid connection handle leaks" feature I mentioned
recently).
I think what is happening is that connection.close() is modifying the
list of connections, and thus next() is detecting the change and
throwing the CME.
At the moment I don't understand why the sun code is calling cleanup
on a managed connection with any handles, so there may be other
problems here as well.
thanks
david jencks
On Oct 29, 2006, at 7:23 AM, Pavel Palát wrote:
> 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.closeUserConnec
> tion(AbstractConnectorAllocator.java:157)
> com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.componentD
> estroyed(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
>
>
>
>
> Yahoo! Groups Links
>
>
>
>