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().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]




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



Reply via email to