I believe that I have solved this problem, and that there is a bug in OJB.
I cannot be sure, but with the fix, the app has been running for 10 days now
with no reported errors.

It seems that in certain circumstances an old connection will be reused, and
it will not be validated (or checked for being alive).

The following conditions are required for the error to occur :
1. An object is cached (it will only happen with a long term cache - eg
ObjectCacheDefaultImpl)
2. The object has been cached for long enough for the database connection
that was used to load it has expired
3. The object was loaded from outside a transaction (or possibly also inside
a very long living transaction)
4. A collection proxy (not sure if it affects other proxies) is materialised
from within this
object

What seems to happen, is the connection which was used to load the object is
held onto, and when the collection is materialised it reuses this stale
connection and crashes out.  It might also be caused if it has already been
materialised and refresh=true - not sure how that works though.

This bug will only affect people using OJB in accordance with the above
criteria.  ObjectCachePerBrokerImpl shouldn't be affected.  Also the bug
wont apply if using transactions - as when it is closed it drops the
connection.

The solution is in ConnectionManagerImpl.getConnection method.  The code is
already there, but commented out:
>
>         // if (con == null || !isAlive(con))
>         // isAlive check, how do we react if false and we in tx?
>         // create a new connection isn't the right way I think.
>         if (con == null)

I think this code should be applied - or at the very least, should be
modified and applied if not inside a transaction:

if (con == null || (!isInLocalTransaction() && !isAlive(con)) )

Daniel.

> -----Original Message-----
> From: Daniel Perry [mailto:[EMAIL PROTECTED]
> Sent: 02 November 2004 11:14
> To: OJB Users List
> Subject: RE: SQLExcpetion
>
>
> Once again our app has started getting these errors (see trace below). It
> seems to be happening after several days of operation.
>
> The problem always seems to happen when iterating over a proxied
> collection
> in a jsp (using jakarta JSTL c:forEach tag).
>
> See comments below:
>
> > Is the error always caused by the same class
> >
> >  >>>>at
> >  >>>>org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForE
> >  >>>
> >  >>>achIterator
> >
> > or always caused when materialized a proxied collection?
>
> Yes it's caused by that same class, but not always from the same jsp.
>
> But it's also always when proxied collections are materialised.
>
> >
> > Does the error occur when OJB materialize a class with clob/blob or
> > binary/object field?
> >
>
> Dont think so.
>
> > > Is there a way for me to clear the connection pool?
> >
> > You can try
> > ConnectionFactoryFactory.createConnectionFactory().releaseAllResources()
> > CFF is a singleton. This call clear the used pool and close all
> > connections of the pool (connections in use will be ignored AFAIK)
> >
> > Or extend ConnectionFactoryPooledImpl and add your own
> monitoring methods.
>
>
> I've tried clearing the connection pool every hour, so the connections
> should be fine.  I havnt tried clearing the cache...
>
> How are connections obtained when cached objects have their proxied
> collections materialised? (note no transactions are being used)
>
> I think an object is being loaded, and stuck in the cache.  Days later the
> object is being used and is having a proxied collection materialised, and
> this is using the origional connection.
>
> From what i can see in the code, a collection proxy obtains a broker, the
> broker obtains a connection - but (and i might have got the code
> wrong here)
> it should reuse the broker it used when it was initally loaded,
> and then the
> broker reuses the conenction without checking it isnt closed :
> ConnectionManagerImpl.getConnection
>
>         // if (con == null || !isAlive(con))
>         // isAlive check, how do we react if false and we in tx?
>         // create a new connection isn't the right way I think.
>         if (con == null)
>
> This only checks if it has a connection, not if the connection is valid.
> Maybe i should reinstate the (con == null || !isAlive(con)) ???
>
> Could this be the cause of my problem? or am i way off track!
>
> Daniel.
>
> Stack trace:
>
> org.apache.jasper.JasperException:
> org.apache.ojb.broker.PersistenceBrokerException:
> org.apache.ojb.broker.PersistenceBrokerSQLException:
> java.sql.SQLException:
> No operations allowed after connection closed.
>
> Connection was closed due to the following exception:
>
> ** BEGIN NESTED EXCEPTION **
>
> java.sql.SQLException
> MESSAGE: Communication link failure: java.io.IOException,
> underlying cause:
> Unexpected end of input stream
>
> ** BEGIN NESTED EXCEPTION **
>
> java.io.IOException
> MESSAGE: Unexpected end of input stream
>
> STACKTRACE:
>
> java.io.IOException: Unexpected end of input stream
>         at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:1455)
>         at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:1826)
>         at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1098)
>         at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1192)
>         at com.mysql.jdbc.Connection.execSQL(Connection.java:2051)
>         at
> com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1496)
>         at
> org.apache.ojb.broker.accesslayer.JdbcAccessImpl.executeQuery(Unknown
> Source)
>         at
> org.apache.ojb.broker.accesslayer.RsQueryObject.performQuery(Unkno
> wn Source)
>         at org.apache.ojb.broker.accesslayer.RsIterator.<init>(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.RsIteratorFactoryImpl.createRsIterator(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.PersistenceBrokerImpl.getRsIteratorFrom
> Query(Unkn
> own Source)
>         at
> org.apache.ojb.broker.core.PersistenceBrokerImpl.getIteratorFromQu
> ery(Unknow
> n Source)
>         at
> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQue
> ry(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.QueryReferenceBroker.getCollectionByQue
> ry(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.PersistenceBrokerImpl.getCollectionByQu
> ery(Unknow
> n Source)
>         at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollecti
> onByQuery(
> Unknown Source)
>         at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.getCollecti
> onByQuery(
> Unknown Source)
>         at
> org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.loadDa
> ta(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl.loadData(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.getDat
> a(Unknown
> Source)
>         at
> org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl.iterat
> or(Unknown
> Source)
>         at
> org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEa
> chIterator
> (ForEachSupport.java:329)
>         at
> org.apache.taglibs.standard.tag.common.core.ForEachSupport.support
> edTypeForE
> achIterator(ForEachSupport.java:205)
>         at
> org.apache.taglibs.standard.tag.common.core.ForEachSupport.prepare
> (ForEachSu
> pport.java:137)
>         at
> javax.servlet.jsp.jstl.core.LoopTagSupport.doStartTag(LoopTagSuppo
> rt.java:22
> 7)
>         at
> org.apache.jsp.WEB_002dINF.jsps.manager.behavioursscreen.appraisal
> _jsp._jspx
> _meth_c_forEach_0(appraisal_jsp.java:294)
>         at
> org.apache.jsp.WEB_002dINF.jsps.manager.behavioursscreen.appraisal
> _jsp._jspS
> ervice(appraisal_jsp.java:186)
>         at
> org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>         at
> org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrap
> per.java:2
> 98)
>         at
> org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
>         at
> org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(A
> pplication
> FilterChain.java:237)
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(Applicati
> onFilterCh
> ain.java:157)
>         at
> org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationD
> ispatcher.
> java:703)
>         at
> org.apache.catalina.core.ApplicationDispatcher.processRequest(Appl
> icationDis
> patcher.java:463)
>         at
> org.apache.catalina.core.ApplicationDispatcher.doForward(Applicati
> onDispatch
> er.java:398)
>         at
> org.apache.catalina.core.ApplicationDispatcher.forward(Application
> Dispatcher
> .java:312)
>         at
> org.apache.struts.action.RequestProcessor.doForward(RequestProcess
> or.java:10
> 56)
>         at
> org.apache.struts.action.RequestProcessor.processForwardConfig(Req
> uestProces
> sor.java:388)
>         at
> org.apache.struts.action.RequestProcessor.process(RequestProcessor
> .java:231)
>         at
> org.apache.struts.action.ActionServlet.process(ActionServlet.java:1158)
>         at
> org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
>         at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(A
> pplication
> FilterChain.java:237)
>         at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(Applicati
> onFilterCh
> ain.java:157)
>         at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapp
> erValve.ja
> va:214)
>         at
> org.apache.catalina.core.StandardValveContext.invokeNext(StandardV
> alveContex
> t.java:104)
>         at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.
> java:520)
>         at
> org.apache.catalina.core.StandardContextValve.invokeInternal(Stand
> ardContext
> Valve.java:198)
>         at
> org.apache.catalina.core.StandardContextValve.invoke(StandardConte
> xtValve.ja
> va:152)
>         at
> org.apache.catalina.core.StandardValveContext.invokeNext(StandardV
> alveContex
> t.java:104)
>         at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.
> java:520)
>         at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValv
> e.java:137
> )
>         at
> org.apache.catalina.core.StandardValveContext.invokeNext(StandardV
> alveContex
> t.java:104)
>         at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValv
> e.java:117
> )
>         at
> org.apache.catalina.core.StandardValveContext.invokeNext(StandardV
> alveContex
> t.java:102)
>         at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.
> java:520)
>         at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngine
> Valve.java
> :109)
>         at
> org.apache.catalina.core.StandardValveContext.invokeNext(StandardV
> alveContex
> t.java:104)
>         at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.
> java:520)
>         at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
>         at
> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
>         at
> org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:296)
>         at
> org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:372)
>         at
> org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:694)
>         at
> org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket
> .java:626)
>         at
> org.apache.jk.common.SocketConnection.runIt(ChannelSocket.java:807)
>         at
> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(Thre
> adPool.jav
> a:644)
>         at java.lang.Thread.run(Thread.java:534)
>
>
> ** END NESTED EXCEPTION **
>
>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to