diff --git a/src/main/java/com/zaxxer/hikari/proxy/CallableStatementProxy.java b/src/main/java/com/zaxxer/hikari/proxy/CallableStatementProxy.java
index 9cd50236..8f73f586 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/CallableStatementProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/CallableStatementProxy.java
@@ -19,6 +19,23 @@ package com.zaxxer.hikari.proxy;
import java.sql.CallableStatement;
/**
+ * This is the proxy class for java.sql.CallableStatement. It is used in two ways:
+ *
+ * 1) If instrumentation is not used, Javassist will generate a new class
+ * that extends this class and delegates all method calls to the 'delegate'
+ * member (which points to the real Connection).
+ *
+ * 2) If instrumentation IS used, Javassist will be used to inject all of
+ * the &HikariInject and &HikariOverride annotated fields and methods
+ * of this class into the actual CallableStatement implementation provided by the
+ * JDBC driver. In order to avoid name conflicts some of the fields and
+ * methods are prefixed with _ or __.
+ *
+ * Methods prefixed with __, like __executeQuery() are especially
+ * important because when we inject out own executeQuery() into the
+ * target implementation, the original method is renamed to __executeQuery()
+ * so that the call operates the same whether delegation or instrumentation
+ * is used.
*
* @author Brett Wooldridge
*/
@@ -33,6 +50,7 @@ public abstract class CallableStatementProxy extends PreparedStatementProxy impl
// Overridden java.sql.CallableStatement Methods
// **********************************************************************
+
// ***********************************************************************
// These methods contain code we do not want injected into the actual
// java.sql.Connection implementation class. These methods are only
diff --git a/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java b/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
index 2284571a..82e19074 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
@@ -32,18 +32,23 @@ import com.zaxxer.hikari.javassist.HikariInject;
import com.zaxxer.hikari.javassist.HikariOverride;
/**
- * This is the proxy class for java.sql.Connection. It is used in
- * two ways:
+ * This is the proxy class for java.sql.Connection. It is used in two ways:
*
* 1) If instrumentation is not used, Javassist will generate a new class
* that extends this class and delegates all method calls to the 'delegate'
* member (which points to the real Connection).
*
* 2) If instrumentation IS used, Javassist will be used to inject all of
- * the non-final methods of this class into the actual Connection implementation
- * provided by the JDBC driver. All of the fields, except for PROXY_FACTORY
- * and 'delegate' are also injected. In order to avoid name conflicts the
- * fields of this class have slightly unconventional names.
+ * the &HikariInject and &HikariOverride annotated fields and methods
+ * of this class into the actual Connection implementation provided by the
+ * JDBC driver. In order to avoid name conflicts some of the fields and
+ * methods are prefixed with _ or __.
+ *
+ * Methods prefixed with __, like __createStatement() are especially
+ * important because when we inject out own createStatement() into the
+ * target implementation, the original method is renamed to __createStatement()
+ * so that the call operates the same whether delegation or instrumentation
+ * is used.
*
* @author Brett Wooldridge
*/
@@ -77,6 +82,8 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
SQL_ERRORS.add("57P02"); // CRASH SHUTDOWN
SQL_ERRORS.add("01002"); // SQL92 disconnect error
+ // This is important when injecting in instrumentation mode. Do not change
+ // this name without also fixing the HikariClassTransformer.
__static();
}
@@ -84,6 +91,8 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
{
this.delegate = connection;
+ // This is important when injecting in instrumentation mode. Do not change
+ // this name without also fixing the HikariClassTransformer.
__init();
}
@@ -187,11 +196,6 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
return statement;
}
- public final Connection getDelegate()
- {
- return delegate;
- }
-
// **********************************************************************
// "Overridden" java.sql.Connection Methods
// **********************************************************************
diff --git a/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java b/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java
index 026f47d3..5cd79a8d 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java
@@ -28,6 +28,7 @@ import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
+import javassist.LoaderClassPath;
import javassist.Modifier;
import com.zaxxer.hikari.util.ClassLoaderUtils;
@@ -58,10 +59,9 @@ public final class JavassistProxyFactoryFactory
private JavassistProxyFactoryFactory()
{
- ClassPool defaultPool = ClassPool.getDefault();
- classPool = new ClassPool(defaultPool);
+ classPool = new ClassPool();
classPool.importPackage("java.sql");
- classPool.childFirstLookup = true;
+ classPool.appendClassPath(new LoaderClassPath(this.getClass().getClassLoader()));
try
{
@@ -86,8 +86,9 @@ public final class JavassistProxyFactoryFactory
private ProxyFactory generateProxyFactory() throws Exception
{
- CtClass targetCt = classPool.makeClass("com.zaxxer.hikari.proxy.JavassistProxyFactory");
- CtClass superCt = classPool.getCtClass("com.zaxxer.hikari.proxy.ProxyFactory");
+ String packageName = ProxyFactory.class.getPackage().getName();
+ CtClass targetCt = classPool.makeClass(packageName + ".JavassistProxyFactory");
+ CtClass superCt = classPool.getCtClass(ProxyFactory.class.getName());
targetCt.setSuperclass(superCt);
targetCt.setModifiers(Modifier.FINAL);
@@ -98,23 +99,23 @@ public final class JavassistProxyFactoryFactory
StringBuilder call = new StringBuilder("{");
if ("getProxyConnection".equals(method.getName()))
{
- call.append("return new com.zaxxer.hikari.proxy.ConnectionJavassistProxy($$);");
+ call.append("return new ").append(packageName).append(".ConnectionJavassistProxy($$);");
}
if ("getProxyStatement".equals(method.getName()))
{
- call.append("return $2 != null ? new com.zaxxer.hikari.proxy.StatementJavassistProxy($$) : null;");
+ call.append("return $2 != null ? new ").append(packageName).append(".StatementJavassistProxy($$) : null;");
}
if ("getProxyPreparedStatement".equals(method.getName()))
{
- call.append("return $2 != null ? new com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy($$) : null;");
+ call.append("return $2 != null ? new ").append(packageName).append(".PreparedStatementJavassistProxy($$) : null;");
}
if ("getProxyResultSet".equals(method.getName()))
{
- call.append("return $2 != null ? new com.zaxxer.hikari.proxy.ResultSetJavassistProxy($$) : null;");
+ call.append("return $2 != null ? new ").append(packageName).append(".ResultSetJavassistProxy($$) : null;");
}
if ("getProxyCallableStatement".equals(method.getName()))
{
- call.append("return $2 != null ? new com.zaxxer.hikari.proxy.CallableStatementJavassistProxy($$) : null;");
+ call.append("return $2 != null ? new ").append(packageName).append(".CallableStatementJavassistProxy($$) : null;");
}
call.append('}');
method.setBody(call.toString());
diff --git a/src/main/java/com/zaxxer/hikari/proxy/PreparedStatementProxy.java b/src/main/java/com/zaxxer/hikari/proxy/PreparedStatementProxy.java
index cbc37aee..4ccfe775 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/PreparedStatementProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/PreparedStatementProxy.java
@@ -23,6 +23,23 @@ import java.sql.SQLException;
import com.zaxxer.hikari.javassist.HikariOverride;
/**
+ * This is the proxy class for java.sql.PreparedStatement. It is used in two ways:
+ *
+ * 1) If instrumentation is not used, Javassist will generate a new class
+ * that extends this class and delegates all method calls to the 'delegate'
+ * member (which points to the real Connection).
+ *
+ * 2) If instrumentation IS used, Javassist will be used to inject all of
+ * the &HikariInject and &HikariOverride annotated fields and methods
+ * of this class into the actual PreparedStatement implementation provided by the
+ * JDBC driver. In order to avoid name conflicts some of the fields and
+ * methods are prefixed with _ or __.
+ *
+ * Methods prefixed with __, like __executeQuery() are especially
+ * important because when we inject out own executeQuery() into the
+ * target implementation, the original method is renamed to __executeQuery()
+ * so that the call operates the same whether delegation or instrumentation
+ * is used.
*
* @author Brett Wooldridge
*/
@@ -42,13 +59,7 @@ public abstract class PreparedStatementProxy extends StatementProxy implements I
{
try
{
- ResultSet rs = __executeQuery();
- if (rs != null)
- {
- ((IHikariResultSetProxy) rs)._setProxyStatement(this);
- }
-
- return rs;
+ return _trackResultSet(__executeQuery());
}
catch (SQLException e)
{
@@ -66,10 +77,6 @@ public abstract class PreparedStatementProxy extends StatementProxy implements I
public ResultSet __executeQuery() throws SQLException
{
ResultSet resultSet = ((PreparedStatement) delegate).executeQuery();
- if (resultSet != null)
- {
- resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
- }
- return resultSet;
+ return wrapResultSet(resultSet);
}
}
diff --git a/src/main/java/com/zaxxer/hikari/proxy/ResultSetProxy.java b/src/main/java/com/zaxxer/hikari/proxy/ResultSetProxy.java
index 05a1643a..493129eb 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/ResultSetProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/ResultSetProxy.java
@@ -23,6 +23,18 @@ import java.sql.Statement;
import com.zaxxer.hikari.javassist.HikariInject;
/**
+ * This is the proxy class for java.sql.ResultSet. It is used in two ways:
+ *
+ * 1) If instrumentation is not used, Javassist will generate a new class
+ * that extends this class and delegates all method calls to the 'delegate'
+ * member (which points to the real Connection).
+ *
+ * 2) If instrumentation IS used, Javassist will be used to inject all of
+ * the &HikariInject and &HikariOverride annotated fields and methods
+ * of this class into the actual ResultSet implementation provided by the
+ * JDBC driver. In order to avoid name conflicts some of the fields and
+ * methods are prefixed with _ or __.
+ *
* @author Brett Wooldridge
*/
public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet
diff --git a/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java b/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
index cace42f4..fcbf67e7 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
@@ -25,6 +25,24 @@ import com.zaxxer.hikari.javassist.HikariInject;
import com.zaxxer.hikari.javassist.HikariOverride;
/**
+ * This is the proxy class for java.sql.Statement. It is used in two ways:
+ *
+ * 1) If instrumentation is not used, Javassist will generate a new class
+ * that extends this class and delegates all method calls to the 'delegate'
+ * member (which points to the real Connection).
+ *
+ * 2) If instrumentation IS used, Javassist will be used to inject all of
+ * the &HikariInject and &HikariOverride annotated fields and methods
+ * of this class into the actual Statement implementation provided by the
+ * JDBC driver. In order to avoid name conflicts some of the fields and
+ * methods are prefixed with _ or __.
+ *
+ * Methods prefixed with __, like __executeQuery() are especially
+ * important because when we inject out own executeQuery() into the
+ * target implementation, the original method is renamed to __executeQuery()
+ * so that the call operates the same whether delegation or instrumentation
+ * is used.
+ *
* @author Brett Wooldridge
*/
public abstract class StatementProxy implements IHikariStatementProxy, Statement
@@ -39,6 +57,8 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
static
{
+ // This is important when injecting in instrumentation mode. Do not change
+ // this name without also fixing the HikariClassTransformer.
__static();
}
@@ -71,6 +91,16 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{
}
+ @HikariInject
+ protected T _trackResultSet(T resultSet)
+ {
+ if (resultSet != null)
+ {
+ ((IHikariResultSetProxy) resultSet)._setProxyStatement(this);
+ }
+ return resultSet;
+ }
+
// **********************************************************************
// Overridden java.sql.Statement Methods
// **********************************************************************
@@ -85,6 +115,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
_isClosed = true;
_connection._unregisterStatement(this);
+
try
{
__close();
@@ -100,13 +131,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{
try
{
- ResultSet rs = __executeQuery(sql);
- if (rs != null)
- {
- ((IHikariResultSetProxy) rs)._setProxyStatement(this);
- }
-
- return rs;
+ return _trackResultSet(__executeQuery(sql));
}
catch (SQLException e)
{
@@ -119,13 +144,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{
try
{
- ResultSet rs = __getResultSet();
- if (rs != null)
- {
- ((IHikariResultSetProxy) rs)._setProxyStatement(this);
- }
-
- return rs;
+ return _trackResultSet(__getResultSet());
}
catch (SQLException e)
{
@@ -138,13 +157,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{
try
{
- ResultSet rs = __getGeneratedKeys();
- if (rs != null)
- {
- ((IHikariResultSetProxy) rs)._setProxyStatement(this);
- }
-
- return rs;
+ return _trackResultSet(__getGeneratedKeys());
}
catch (SQLException e)
{
@@ -184,31 +197,26 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
public ResultSet __executeQuery(String sql) throws SQLException
{
- ResultSet resultSet = delegate.executeQuery(sql);
- if (resultSet != null)
- {
- resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
- }
- return resultSet;
+ return wrapResultSet(delegate.executeQuery(sql));
}
public ResultSet __getGeneratedKeys() throws SQLException
{
- ResultSet generatedKeys = delegate.getGeneratedKeys();
- if (generatedKeys != null)
- {
- generatedKeys = PROXY_FACTORY.getProxyResultSet(this, generatedKeys);
- }
- return generatedKeys;
+ return wrapResultSet(delegate.getGeneratedKeys());
}
public ResultSet __getResultSet() throws SQLException
{
- ResultSet resultSet = delegate.getResultSet();
+ return wrapResultSet(delegate.getResultSet());
+ }
+
+ protected ResultSet wrapResultSet(ResultSet resultSet)
+ {
if (resultSet != null)
{
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
}
- return resultSet;
+
+ return resultSet;
}
}
\ No newline at end of file