No problem. I've not come accross many bugs (well serious ones) in OJB, but it's nice to find a hole and hopefully prevent it causing problems for other people. I'm just glad it's sorted now, and our clients app isnt crashing anymore.
I agree with your comments on cleaning up a bit better. The code seems to do better if transactions are used, but much of my code doesnt have any requirement for them. Thanks, Daniel. > -----Original Message----- > From: Armin Waibel [mailto:[EMAIL PROTECTED] > Sent: 16 November 2004 12:53 > To: OJB Users List > Subject: Re: Bug identified (was RE: SQLExcpetion) > > > Hi Daniel, > > many thanks for your detailed description and suggestion. > > > > > 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)) ) > > > > I will check in your patch ASAP. Additionally I think we should release > the closed connection instance and I will do a minor refactoring of > CollectionProxyDefaultImpl to handle the used PB instance more strict. > > > regards, > Armin > > > Daniel Perry wrote: > > > 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().releaseAllRe > sources() > >>>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.createRsIterato > r(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] > > > > > > > > --------------------------------------------------------------------- > 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]
