Author: ojacobson
Date: Tue Jun 30 11:59:22 2009
New Revision: 4454
Log:
AOP adapter for logging db connection acquire/releases.
Added:
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/Connection\
LeakDetector.java
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/ProxyConne\
ction.java
Modified:
congo/branches/congo-2.0.0.2/pom.xml
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/dao/InvoiceDAO.ja\
va
congo/branches/congo-2.0.0.2/src/main/webapp/WEB-INF/applicationContext.xml
Modified: congo/branches/congo-2.0.0.2/pom.xml
==============================================================================
--- congo/branches/congo-2.0.0.2/pom.xml [iso-8859-1] (original)
+++ congo/branches/congo-2.0.0.2/pom.xml [iso-8859-1] Tue Jun 30 11:59:22 2009
@@ -21,6 +21,12 @@
<artifactId>struts2-spring-plugin</artifactId>
<version>2.1.2</version>
<scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.6.2</version>
</dependency>
<dependency>
@@ -171,6 +177,11 @@
<artifactId>liquibase-core</artifactId>
<version>1.8.1</version>
</dependency>
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjweaver</artifactId>
+ <version>1.6.2</version>
+ </dependency>
</dependencies>
<build>
Modified:
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/dao/InvoiceDAO.ja\
va
==============================================================================
---
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/dao/InvoiceDAO.ja\
va [iso-8859-1] (original)
+++
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/dao/InvoiceDAO.ja\
va [iso-8859-1] Tue Jun 30 11:59:22 2009
@@ -61,9 +61,9 @@
}
public Invoice getInvoice(int whatInvoice) throws SQLException {
- Connection c = dataSource.getConnection();
- Invoice i = null;
- logger.info("Retrieving invoice # " + whatInvoice);
+ logger.info("Retrieving invoice # " + whatInvoice);
+ Invoice i = null;
+ Connection c = dataSource.getConnection();
try {
PreparedStatement p;
p = c.prepareStatement(SQL_GET_INVOICE);
@@ -83,8 +83,8 @@
}
public List<Invoice> listInvoices(int cid) throws SQLException {
- Connection c = dataSource.getConnection();
- logger.info("Retrieving invoices for convention " + cid);
+ logger.info("Retrieving invoices for convention " + cid);
+ Connection c = dataSource.getConnection();
try {
PreparedStatement p;
p = c.prepareStatement(SQL_LIST_INVOICE);
@@ -288,9 +288,9 @@
*/
public int getNextSequence(int invoiceNumber) throws SQLException {
logger.debug("Calculating next sequence number for a detail item...");
- Connection c = dataSource.getConnection();
PreparedStatement p;
int nextsequence=1;
+ Connection c = dataSource.getConnection();
try {
p = c.prepareStatement(SQL_NEXT_SEQUENCE);
p.setInt(1,invoiceNumber);
Added:
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/Connection\
LeakDetector.java
==============================================================================
---
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/Connection\
LeakDetector.java (added)
+++
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/Connection\
LeakDetector.java [iso-8859-1] Tue Jun 30 11:59:22 2009
@@ -1,0 +1,12 @@
+package com.stonekeep.congo.spring;
+
+import java.sql.Connection;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+
+public class ConnectionLeakDetector {
+ public Object getConnection(ProceedingJoinPoint joinpoint) throws Throwable
{
+ Connection connection = (Connection) joinpoint.proceed();
+ return new ProxyConnection(connection);
+ }
+}
Added:
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/ProxyConne\
ction.java
==============================================================================
---
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/ProxyConne\
ction.java (added)
+++
congo/branches/congo-2.0.0.2/src/main/java/com/stonekeep/congo/spring/ProxyConne\
ction.java [iso-8859-1] Tue Jun 30 11:59:22 2009
@@ -1,0 +1,263 @@
+package com.stonekeep.congo.spring;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+
+public class ProxyConnection implements Connection {
+
+ private final Logger log = Logger.getLogger(ProxyConnection.class);
+ private final Connection base;
+
+ public ProxyConnection(Connection base) {
+ int identityHashCode = System.identityHashCode(base);
+ Throwable t = new Throwable(String.format("New connection %d",
+ identityHashCode));
+ t.fillInStackTrace();
+ log
+ .debug(String.format("Connection obtained: %d",
+ identityHashCode), t);
+
+ this.base = base;
+ }
+
+ public void clearWarnings() throws SQLException {
+ base.clearWarnings();
+ }
+
+ public void close() throws SQLException {
+ int identityHashCode = System.identityHashCode(base);
+ Throwable t = new Throwable(String.format("Releasing %d",
+ identityHashCode));
+ t.fillInStackTrace();
+ log
+ .debug(String.format("Connection released: %d",
+ identityHashCode), t);
+
+ base.close();
+ }
+
+ public void commit() throws SQLException {
+ base.commit();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements)
+ throws SQLException {
+ return base.createArrayOf(typeName, elements);
+ }
+
+ public Blob createBlob() throws SQLException {
+ return base.createBlob();
+ }
+
+ public Clob createClob() throws SQLException {
+ return base.createClob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return base.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return base.createSQLXML();
+ }
+
+ public Statement createStatement() throws SQLException {
+ return base.createStatement();
+ }
+
+ public Statement createStatement(int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return base.createStatement(resultSetType, resultSetConcurrency,
+ resultSetHoldability);
+ }
+
+ public Statement createStatement(int resultSetType, int
resultSetConcurrency)
+ throws SQLException {
+ return base.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes)
+ throws SQLException {
+ return base.createStruct(typeName, attributes);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return base.getAutoCommit();
+ }
+
+ public String getCatalog() throws SQLException {
+ return base.getCatalog();
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return base.getClientInfo();
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return base.getClientInfo(name);
+ }
+
+ public int getHoldability() throws SQLException {
+ return base.getHoldability();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return base.getMetaData();
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return base.getTransactionIsolation();
+ }
+
+ public Map<String, Class<?>> getTypeMap() throws SQLException {
+ return base.getTypeMap();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return base.getWarnings();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return base.isClosed();
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return base.isReadOnly();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return base.isValid(timeout);
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return base.isWrapperFor(iface);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ return base.nativeSQL(sql);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return base.prepareCall(sql, resultSetType, resultSetConcurrency,
+ resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException {
+ return base.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ return base.prepareCall(sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return base.prepareStatement(sql, resultSetType, resultSetConcurrency,
+ resultSetHoldability);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException {
+ return base.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int
autoGeneratedKeys)
+ throws SQLException {
+ return base.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+ throws SQLException {
+ return base.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String[] columnNames)
+ throws SQLException {
+ return base.prepareStatement(sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ return base.prepareStatement(sql);
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ base.releaseSavepoint(savepoint);
+ }
+
+ public void rollback() throws SQLException {
+ base.rollback();
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ base.rollback(savepoint);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ base.setAutoCommit(autoCommit);
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ base.setCatalog(catalog);
+ }
+
+ public void setClientInfo(Properties properties)
+ throws SQLClientInfoException {
+ base.setClientInfo(properties);
+ }
+
+ public void setClientInfo(String name, String value)
+ throws SQLClientInfoException {
+ base.setClientInfo(name, value);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ base.setHoldability(holdability);
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ base.setReadOnly(readOnly);
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return base.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return base.setSavepoint(name);
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ base.setTransactionIsolation(level);
+ }
+
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+ base.setTypeMap(map);
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return base.unwrap(iface);
+ }
+
+}
Modified:
congo/branches/congo-2.0.0.2/src/main/webapp/WEB-INF/applicationContext.xml
==============================================================================
--- congo/branches/congo-2.0.0.2/src/main/webapp/WEB-INF/applicationContext.xml
[iso-8859-1] (original)
+++ congo/branches/congo-2.0.0.2/src/main/webapp/WEB-INF/applicationContext.xml
[iso-8859-1] Tue Jun 30 11:59:22 2009
@@ -1,9 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd"
default-lazy-init="true">
@@ -227,4 +230,12 @@
<property name="password" value="${database.password}"/>
<property name="testConnectionOnCheckout" value="true"/>
</bean>
+
+ <bean id="com.stonekeep.congo.debug.ConnectionLeaks"
class="com.stonekeep.congo.spring.ConnectionLeakDetector" />
+
+ <aop:config>
+ <aop:aspect ref="com.stonekeep.congo.debug.ConnectionLeaks">
+ <aop:around pointcut="execution(*
javax.sql.DataSource.getConnection(..))" method="getConnection"/>
+ </aop:aspect>
+ </aop:config>
</beans>