I use a different method to close the connection pool with DBCP 1.1
/**
* Close connection pool.
* Will close the real connections in the pool
* Use this method before application shutdown
*/
public void closeConnectionPool() {
try {
connectionPool.close();
} catch (Exception e) {
log.warning("Problem closing database connection pool");
log.warning(e.getMessage());
}
}
-- John Zoetebier Web site: http://www.transparent.co.nz
Hi,
I've recently upgraded to the latest version of Tomcat (4.1.29), which includes DBCP 1.1, over 1.0 in previous versions.
On starting my application and attempting to logon to it, it falls over with a NullPointerException, included here: java.lang.NullPointerException at oracle.jdbc.driver.ScrollableResultSet.close(ScrollableResultSet.java:14 9) at org.apache.commons.dbcp.DelegatingResultSet.close(DelegatingResultSet.ja va:193) at org.apache.commons.dbcp.DelegatingResultSet.close(DelegatingResultSet.ja va:193) at org.apache.commons.dbcp.DelegatingPreparedStatement.passivate(Delegating PreparedStatement.java:298) at org.apache.commons.dbcp.DelegatingPreparedStatement.close(DelegatingPrep aredStatement.java:185) at com.pcmsgroup.v21.star.framework.persistence.BaseDbDAO.releaseResources( BaseDbDAO.java:205) at com.pcmsgroup.v21.star.persistence.logon.LogonDbDAO.fetchByLogonName(Log onDbDAO.java:149) at com.pcmsgroup.v21.star.domain.logon.Logon.logon(Logon.java:95) at com.pcmsgroup.v21.star.service.logon.LogonService.logon(LogonService.jav a:52) at com.pcmsgroup.v21.star.application.logon.LogonCtrl.process(LogonCtrl.jav a:87) at com.pcmsgroup.v21.star.framework.application.BaseCtrl.execute(BaseCtrl.j ava:180) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestPr ocessor.java:484) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java: 274) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525) at javax.servlet.http.HttpServlet.service(HttpServlet.java:760) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica tionFilterChain.java:247) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt erChain.java:193) at com.pcmsgroup.v21.star.application.logon.LogonFilter.doFilter(LogonFilte r.java:168) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica tionFilterChain.java:213) ...
I've looked around the web, and in your CVS, and think that this is a bug.
The code in com.pcmsgroup.v21.star.framework.persistence.BaseDbDAO.releaseResources is as follows:
public final void releaseResources(Connection connection, PreparedStatement ps, ResultSet rs) throws PersistenceException { try { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } if (connection != null) { // get the Factory ConnectionFactory factory = ConnectionFactory.getInstance(); // turn the Connection back to pool factory.releaseConnection(connection); } } catch (SQLException sqle) { thisLog.error("Failed to release resources", sqle); } catch (Exception e) { thisLog.error("Failed to release resources", e); throw new PersistenceException(e); } }
As you can see, we close ResultSet, PreparedStatement and Connection in the reverse order of that which we got them in. On DBCP 1.0, this used to work fine. According to the JDK API docs: "When a Statement object is closed, its current ResultSet object, if one exists, is also closed." Thus closing the statement after closing the result set is safe.
However, for DBCP 1.1, a change was made to DelegatingPreparedStatement (version 1.6 to 1.7), to "ensure PreparedStatment can only be closed once", which entailed changing:
public void close() throws SQLException { passivate(); _stmt.close(); }
to:
public void close() throws SQLException { _stmt.close(); passivate(); }
I believe this has introduced my problem and is a bug. As now, following the logic:
- The statement is closed, and in accordance with the JDK docs, the result set is closed. - The passivate method is then called, which calls ResultSet.close on the underlying result set, regardless of whether it has been closed already. - This causes the underlying result set, which is already closed to try to close again, thus the NullPointer.
I couldn't spot this in the bug reports, so could someone answer if this is a bug or not, or is there something I am doing wrong, or should this be directed at the developers list? I don't believe I should quietly catch Exception's in the close() methods as per your examples, as I'd really like to know if there are problems!
Thanks
Simon
The information contained in this e-mail is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. If You are not the intended recipient of this e-mail, the use of this information or any disclosure, copying or distribution is Prohibited and may be unlawful. If you received this in error, please contact the sender and delete the material from any computer. The views expressed in this e-mail may not necessarily be the views of The PCMS Group plc and should not be taken as authority to carry out any instruction contained.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
