Add code to trap SQLExceptions and call a checkException() method.

pull/1/head
Brett Wooldridge 11 years ago
parent 03a44b7ab5
commit 72d3d38af6

@ -34,22 +34,39 @@ public class CallableStatementProxy extends HikariProxyBase<CallableStatement>
protected CallableStatementProxy()
{
// Default constructor
super(null);
}
protected CallableStatementProxy(ConnectionProxy jdbcPooledConnection, CallableStatement statement)
protected CallableStatementProxy(ConnectionProxy connection, CallableStatement statement)
{
initialize(jdbcPooledConnection, statement);
super(statement);
this.proxy = this;
this.connection = connection;
}
void initialize(ConnectionProxy connection, CallableStatement statement)
// void initialize(ConnectionProxy connection, CallableStatement statement)
// {
// this.proxy = this;
// this.connection = connection;
// this.delegate = statement;
// }
SQLException checkException(SQLException e)
{
this.proxy = this;
this.connection = connection;
this.delegate = statement;
return connection.checkException(e);
}
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
/* Overridden methods of java.sql.CallableStatement */
// **********************************************************************
// Overridden java.sql.CallableStatement Methods
// other methods are injected
// **********************************************************************
public void close() throws SQLException
{
@ -97,10 +114,4 @@ public class CallableStatementProxy extends HikariProxyBase<CallableStatement>
}
throw new SQLException(getClass().getName() + " is not a wrapper for " + iface);
}
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
}

@ -21,7 +21,6 @@ import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Map;
@ -64,21 +63,22 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
protected ConnectionProxy()
{
super(null);
}
protected ConnectionProxy(HikariPool parentPool, Connection connection)
{
super(connection);
this.parentPool = parentPool;
this.proxy = this;
this.delegate = connection;
}
void initialize(HikariPool parentPool, Connection connection)
{
this.parentPool = parentPool;
this.proxy = this;
this.delegate = connection;
}
// void initialize(HikariPool parentPool, Connection connection)
// {
// this.parentPool = parentPool;
// this.proxy = this;
// this.delegate = connection;
// }
void unregisterStatement(Object statement)
{
@ -113,10 +113,12 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
stackTrace = new StackTraceElement[trace.length - 4];
System.arraycopy(trace, 4, stackTrace, 0, stackTrace.length);
final long leakTime = System.currentTimeMillis() + leakDetectionThreshold;
leakTask = new TimerTask() {
public void run() {
leakTask = new TimerTask()
{
public void run()
{
if (System.currentTimeMillis() > leakTime)
{
Exception e = new Exception();
@ -130,6 +132,11 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
scheduler.schedule(leakTask, leakDetectionThreshold);
}
SQLException checkException(SQLException e)
{
return e;
}
@Override
protected Map<String, Method> getMethodMap()
{
@ -138,6 +145,7 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
// **********************************************************************
// Overridden java.sql.Connection Methods
// other methods are injected
// **********************************************************************
/* (non-Javadoc)
@ -153,13 +161,22 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
leakTask = null;
}
final Statement[] statements = openStatements.toArray(new Statement[0]);
for (int i = 0; i < statements.length; i++)
try
{
statements[i].close();
final Statement[] statements = openStatements.toArray(new Statement[0]);
for (int i = 0; i < statements.length; i++)
{
statements[i].close();
}
}
catch (SQLException e)
{
throw checkException(e);
}
finally
{
parentPool.releaseConnection((IHikariConnectionProxy) proxy);
}
parentPool.releaseConnection((IHikariConnectionProxy) proxy);
}
}
@ -176,11 +193,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public Statement createStatement() throws SQLException
{
Statement statement = delegate.createStatement();
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
try
{
Statement statement = delegate.createStatement();
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -188,11 +212,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
{
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency);
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
try
{
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency);
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -200,11 +231,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
try
{
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
Statement statementProxy = ProxyFactory.INSTANCE.getProxyStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -212,11 +250,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public CallableStatement prepareCall(String sql) throws SQLException
{
CallableStatement statement = delegate.prepareCall(sql);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
try
{
CallableStatement statement = delegate.prepareCall(sql);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -224,11 +269,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
try
{
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -236,11 +288,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
try
{
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
CallableStatement statementProxy = ProxyFactory.INSTANCE.getProxyCallableStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -248,11 +307,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public PreparedStatement prepareStatement(String sql) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
try
{
PreparedStatement statement = delegate.prepareStatement(sql);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -260,23 +326,37 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql, autoGeneratedKeys);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
try
{
PreparedStatement statement = delegate.prepareStatement(sql, autoGeneratedKeys);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
* @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
*/
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
try
{
PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -284,11 +364,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
try
{
PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -296,11 +383,18 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql, columnIndexes);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
try
{
PreparedStatement statement = delegate.prepareStatement(sql, columnIndexes);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
/* (non-Javadoc)
@ -308,26 +402,17 @@ public class ConnectionProxy extends HikariProxyBase<Connection> implements IHik
*/
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
{
PreparedStatement statement = delegate.prepareStatement(sql, columnNames);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
return statementProxy;
}
/* (non-Javadoc)
* @see java.sql.Connection#rollback()
*/
public void rollback() throws SQLException
{
// TODO Auto-generated method stub
}
try
{
PreparedStatement statement = delegate.prepareStatement(sql, columnNames);
PreparedStatement statementProxy = ProxyFactory.INSTANCE.getProxyPreparedStatement(this, statement);
openStatements.add(statementProxy);
/* (non-Javadoc)
* @see java.sql.Connection#rollback(java.sql.Savepoint)
*/
public void rollback(Savepoint savepoint) throws SQLException
{
// TODO Auto-generated method stub
return statementProxy;
}
catch (SQLException e)
{
throw checkException(e);
}
}
}

@ -20,6 +20,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -29,12 +30,16 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public abstract class HikariProxyBase<T> implements InvocationHandler
{
private final static Map<Method, String> methodKeyMap = new ConcurrentHashMap<Method, String>();
protected Object proxy;
protected T delegate;
final protected T delegate;
protected HikariProxyBase(T delegate)
{
this.delegate = delegate;
}
protected abstract Map<String, Method> getMethodMap();
@ -44,6 +49,8 @@ public abstract class HikariProxyBase<T> implements InvocationHandler
return (T) proxy;
}
abstract SQLException checkException(SQLException e);
@SuppressWarnings("unchecked")
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{

@ -24,14 +24,12 @@ import java.sql.Statement;
import java.util.HashSet;
import java.util.Set;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.NotFoundException;
/**
*
@ -46,6 +44,7 @@ public class JavassistProxyFactoryFactory
{
ClassPool defaultPool = ClassPool.getDefault();
classPool = new ClassPool(defaultPool);
classPool.importPackage("java.sql");
classPool.childFirstLookup = true;
try
@ -114,8 +113,7 @@ public class JavassistProxyFactoryFactory
* Generate Javassist Proxy Classes
*/
@SuppressWarnings("unchecked")
private <T> Class<T> generateProxyClass(Class<T> primaryInterface, Class<?> superClass) throws NotFoundException, CannotCompileException,
NoSuchMethodException, SecurityException
private <T> Class<T> generateProxyClass(Class<T> primaryInterface, Class<?> superClass) throws Exception
{
// Make a new class that extends one of the JavaProxy classes (ie. superClass); use the name to XxxJavassistProxy instead of XxxJavaProxy
String superClassName = superClass.getName();
@ -150,30 +148,29 @@ public class JavassistProxyFactoryFactory
continue;
}
CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null);
// Ignore already added methods that come from other interfaces
if (methods.contains(intfMethod.getName() + intfMethod.getSignature()))
{
continue;
}
CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null);
methods.add(intfMethod.getName() + intfMethod.getSignature());
// Generate a method that simply invokes the same method on the delegate
StringBuilder call = new StringBuilder("{");
if (method.getReturnType() != CtClass.voidType)
String methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { throw checkException(e); } }";
if (method.getReturnType() == CtClass.voidType)
{
call.append("return ");
methodBody = methodBody.replace("return", "");
}
call.append("((").append(primaryInterface.getName()).append(')'); // cast to primary interface
call.append("delegate).");
call.append(method.getName()).append("($$);");
call.append('}');
method.setBody(call.toString());
methodBody = methodBody.replace("cast", primaryInterface.getName());
methodBody = methodBody.replace("method", method.getName());
method.setBody(methodBody);
targetCt.addMethod(method);
}
}
return targetCt.toClass(classPool.getClassLoader(), null); //ClassLoaderUtils.getClassLoader(), null);
return targetCt.toClass(classPool.getClassLoader(), null);
}
}

@ -28,28 +28,31 @@ import java.util.Map;
*/
public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
{
private final static Map<String, Method> selfMethodMap = createMethodMap(PreparedStatementProxy.class);
private final static ProxyFactory proxyFactory = ProxyFactory.INSTANCE;
private final static Map<String, Method> selfMethodMap;
private ConnectionProxy connection;
static
{
selfMethodMap = createMethodMap(PreparedStatementProxy.class);
}
protected PreparedStatementProxy()
{
// Default constructor
super(null);
}
protected PreparedStatementProxy(ConnectionProxy connection, PreparedStatement statement)
{
super(statement);
this.proxy = this;
this.connection = connection;
this.delegate = statement;
}
void initialize(ConnectionProxy connection, PreparedStatement statement)
{
this.proxy = this;
this.connection = connection;
this.delegate = statement;
}
public String toString()
@ -57,7 +60,23 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
return "a PreparedStatementProxy wrapping [" + delegate + "]";
}
/* Overridden methods of java.sql.PreparedStatement */
SQLException checkException(SQLException e)
{
return connection.checkException(e);
}
/* Overridden methods of ProxyBase */
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
// **********************************************************************
// Overridden java.sql.PreparedStatement Methods
// other methods are injected
// **********************************************************************
public void close() throws SQLException
{
@ -68,7 +87,6 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
connection.unregisterStatement(proxy);
delegate.close();
delegate = null;
}
public ResultSet getResultSet() throws SQLException
@ -78,7 +96,7 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
{
return null;
}
return proxyFactory.getProxyResultSet(this.getProxy(), resultSet);
return ProxyFactory.INSTANCE.getProxyResultSet(this.getProxy(), resultSet);
}
public ResultSet executeQuery() throws SQLException
@ -88,7 +106,7 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
{
return null;
}
return proxyFactory.getProxyResultSet(this.getProxy(), resultSet);
return ProxyFactory.INSTANCE.getProxyResultSet(this.getProxy(), resultSet);
}
public ResultSet executeQuery(String sql) throws SQLException
@ -98,7 +116,7 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
{
return null;
}
return proxyFactory.getProxyResultSet(this.getProxy(), resultSet);
return ProxyFactory.INSTANCE.getProxyResultSet(this.getProxy(), resultSet);
}
public ResultSet getGeneratedKeys() throws SQLException
@ -108,7 +126,7 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
{
return null;
}
return proxyFactory.getProxyResultSet(this.getProxy(), generatedKeys);
return ProxyFactory.INSTANCE.getProxyResultSet(this.getProxy(), generatedKeys);
}
/* java.sql.Wrapper implementation */
@ -131,12 +149,4 @@ public class PreparedStatementProxy extends HikariProxyBase<PreparedStatement>
}
throw new SQLException(getClass().getName() + " is not a wrapper for " + iface);
}
/* Overridden methods of ProxyBase */
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
}

@ -33,33 +33,44 @@ public class ResultSetProxy extends HikariProxyBase<ResultSet>
protected ResultSetProxy()
{
// Default constructor
super(null);
}
protected ResultSetProxy(Statement statement, ResultSet resultSet)
{
initialize(statement, resultSet);
}
void initialize(Statement statement, ResultSet resultSet)
{
super(resultSet);
this.proxy = this;
this.statement = statement;
this.delegate = resultSet;
}
/* Overridden methods of java.sql.ResultSet */
// void initialize(Statement statement, ResultSet resultSet)
// {
// this.proxy = this;
// this.statement = statement;
// this.delegate = resultSet;
// }
public Statement getStatement() throws SQLException
protected SQLException checkException(SQLException e)
{
return statement;
return ((HikariProxyBase<?>) statement).checkException(e);
}
/* Overridden methods of ProxyBase */
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
// **********************************************************************
// Overridden java.sql.ResultSet Methods
// other methods are injected
// **********************************************************************
public Statement getStatement() throws SQLException
{
return statement;
}
}

@ -33,24 +33,40 @@ public class StatementProxy extends HikariProxyBase<Statement>
protected StatementProxy()
{
// Default constructor
super(null);
}
protected StatementProxy(ConnectionProxy connection, Statement statement)
{
super(statement);
this.proxy = this;
this.connection = connection;
this.delegate = statement;
}
void initialize(ConnectionProxy connection, Statement statement)
// void initialize(ConnectionProxy connection, Statement statement)
// {
// this.proxy = this;
// this.connection = connection;
// this.delegate = statement;
// }
SQLException checkException(SQLException e)
{
this.proxy = this;
this.connection = connection;
this.delegate = statement;
return connection.checkException(e);
}
/* Overridden methods of java.sql.Statement */
/* Overridden methods of ProxyBase */
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
// **********************************************************************
// Overridden java.sql.Statement Methods
// other methods are injected
// **********************************************************************
public void close() throws SQLException
{
@ -61,7 +77,6 @@ public class StatementProxy extends HikariProxyBase<Statement>
connection.unregisterStatement(proxy);
delegate.close();
delegate = null;
}
public ResultSet executeQuery(String sql) throws SQLException
@ -104,12 +119,4 @@ public class StatementProxy extends HikariProxyBase<Statement>
}
throw new SQLException(getClass().getName() + " is not a wrapper for " + iface);
}
/* Overridden methods of ProxyBase */
@Override
protected Map<String, Method> getMethodMap()
{
return selfMethodMap;
}
}
Loading…
Cancel
Save