Merge branch 'dev'

* dev:
  Try to use our own classloader  (the one that loaded the proxy factory itself) in the class pool.
  Compose the package and class names to support jar shading.
  documentation and code simplification.
  JavaDoc
  documentation and dead code removal
  JavaDoc
pull/6/head
Brett Wooldridge 11 years ago
commit a154a3dab4

@ -19,6 +19,23 @@ package com.zaxxer.hikari.proxy;
import java.sql.CallableStatement; 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 * @author Brett Wooldridge
*/ */
@ -33,6 +50,7 @@ public abstract class CallableStatementProxy extends PreparedStatementProxy impl
// Overridden java.sql.CallableStatement Methods // Overridden java.sql.CallableStatement Methods
// ********************************************************************** // **********************************************************************
// *********************************************************************** // ***********************************************************************
// These methods contain code we do not want injected into the actual // These methods contain code we do not want injected into the actual
// java.sql.Connection implementation class. These methods are only // java.sql.Connection implementation class. These methods are only

@ -32,18 +32,23 @@ import com.zaxxer.hikari.javassist.HikariInject;
import com.zaxxer.hikari.javassist.HikariOverride; import com.zaxxer.hikari.javassist.HikariOverride;
/** /**
* This is the proxy class for java.sql.Connection. It is used in * This is the proxy class for java.sql.Connection. It is used in two ways:
* two ways:
* *
* 1) If instrumentation is not used, Javassist will generate a new class * 1) If instrumentation is not used, Javassist will generate a new class
* that extends this class and delegates all method calls to the 'delegate' * that extends this class and delegates all method calls to the 'delegate'
* member (which points to the real Connection). * member (which points to the real Connection).
* *
* 2) If instrumentation IS used, Javassist will be used to inject all of * 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 * the &HikariInject and &HikariOverride annotated fields and methods
* provided by the JDBC driver. All of the fields, <i>except</i> for PROXY_FACTORY * of this class into the actual Connection implementation provided by the
* and 'delegate' are also injected. In order to avoid name conflicts the * JDBC driver. In order to avoid name conflicts some of the fields and
* fields of this class have slightly unconventional names. * 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 * @author Brett Wooldridge
*/ */
@ -77,6 +82,8 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
SQL_ERRORS.add("57P02"); // CRASH SHUTDOWN SQL_ERRORS.add("57P02"); // CRASH SHUTDOWN
SQL_ERRORS.add("01002"); // SQL92 disconnect error 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(); __static();
} }
@ -84,6 +91,8 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
{ {
this.delegate = connection; this.delegate = connection;
// This is important when injecting in instrumentation mode. Do not change
// this name without also fixing the HikariClassTransformer.
__init(); __init();
} }
@ -187,11 +196,6 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy, Connect
return statement; return statement;
} }
public final Connection getDelegate()
{
return delegate;
}
// ********************************************************************** // **********************************************************************
// "Overridden" java.sql.Connection Methods // "Overridden" java.sql.Connection Methods
// ********************************************************************** // **********************************************************************

@ -28,6 +28,7 @@ import javassist.ClassPool;
import javassist.CtClass; import javassist.CtClass;
import javassist.CtMethod; import javassist.CtMethod;
import javassist.CtNewMethod; import javassist.CtNewMethod;
import javassist.LoaderClassPath;
import javassist.Modifier; import javassist.Modifier;
import com.zaxxer.hikari.util.ClassLoaderUtils; import com.zaxxer.hikari.util.ClassLoaderUtils;
@ -58,10 +59,9 @@ public final class JavassistProxyFactoryFactory
private JavassistProxyFactoryFactory() private JavassistProxyFactoryFactory()
{ {
ClassPool defaultPool = ClassPool.getDefault(); classPool = new ClassPool();
classPool = new ClassPool(defaultPool);
classPool.importPackage("java.sql"); classPool.importPackage("java.sql");
classPool.childFirstLookup = true; classPool.appendClassPath(new LoaderClassPath(this.getClass().getClassLoader()));
try try
{ {
@ -86,8 +86,9 @@ public final class JavassistProxyFactoryFactory
private ProxyFactory generateProxyFactory() throws Exception private ProxyFactory generateProxyFactory() throws Exception
{ {
CtClass targetCt = classPool.makeClass("com.zaxxer.hikari.proxy.JavassistProxyFactory"); String packageName = ProxyFactory.class.getPackage().getName();
CtClass superCt = classPool.getCtClass("com.zaxxer.hikari.proxy.ProxyFactory"); CtClass targetCt = classPool.makeClass(packageName + ".JavassistProxyFactory");
CtClass superCt = classPool.getCtClass(ProxyFactory.class.getName());
targetCt.setSuperclass(superCt); targetCt.setSuperclass(superCt);
targetCt.setModifiers(Modifier.FINAL); targetCt.setModifiers(Modifier.FINAL);
@ -98,23 +99,23 @@ public final class JavassistProxyFactoryFactory
StringBuilder call = new StringBuilder("{"); StringBuilder call = new StringBuilder("{");
if ("getProxyConnection".equals(method.getName())) 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())) 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())) 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())) 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())) 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('}'); call.append('}');
method.setBody(call.toString()); method.setBody(call.toString());

@ -23,6 +23,23 @@ import java.sql.SQLException;
import com.zaxxer.hikari.javassist.HikariOverride; 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 &amp;HikariInject and &amp;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 * @author Brett Wooldridge
*/ */
@ -42,13 +59,7 @@ public abstract class PreparedStatementProxy extends StatementProxy implements I
{ {
try try
{ {
ResultSet rs = __executeQuery(); return _trackResultSet(__executeQuery());
if (rs != null)
{
((IHikariResultSetProxy) rs)._setProxyStatement(this);
}
return rs;
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -66,10 +77,6 @@ public abstract class PreparedStatementProxy extends StatementProxy implements I
public ResultSet __executeQuery() throws SQLException public ResultSet __executeQuery() throws SQLException
{ {
ResultSet resultSet = ((PreparedStatement) delegate).executeQuery(); ResultSet resultSet = ((PreparedStatement) delegate).executeQuery();
if (resultSet != null) return wrapResultSet(resultSet);
{
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
}
return resultSet;
} }
} }

@ -23,6 +23,18 @@ import java.sql.Statement;
import com.zaxxer.hikari.javassist.HikariInject; 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 &amp;HikariInject and &amp;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 * @author Brett Wooldridge
*/ */
public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet

@ -25,6 +25,24 @@ import com.zaxxer.hikari.javassist.HikariInject;
import com.zaxxer.hikari.javassist.HikariOverride; 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 &amp;HikariInject and &amp;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 * @author Brett Wooldridge
*/ */
public abstract class StatementProxy implements IHikariStatementProxy, Statement public abstract class StatementProxy implements IHikariStatementProxy, Statement
@ -39,6 +57,8 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
static static
{ {
// This is important when injecting in instrumentation mode. Do not change
// this name without also fixing the HikariClassTransformer.
__static(); __static();
} }
@ -71,6 +91,16 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{ {
} }
@HikariInject
protected <T extends ResultSet> T _trackResultSet(T resultSet)
{
if (resultSet != null)
{
((IHikariResultSetProxy) resultSet)._setProxyStatement(this);
}
return resultSet;
}
// ********************************************************************** // **********************************************************************
// Overridden java.sql.Statement Methods // Overridden java.sql.Statement Methods
// ********************************************************************** // **********************************************************************
@ -85,6 +115,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
_isClosed = true; _isClosed = true;
_connection._unregisterStatement(this); _connection._unregisterStatement(this);
try try
{ {
__close(); __close();
@ -100,13 +131,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{ {
try try
{ {
ResultSet rs = __executeQuery(sql); return _trackResultSet(__executeQuery(sql));
if (rs != null)
{
((IHikariResultSetProxy) rs)._setProxyStatement(this);
}
return rs;
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -119,13 +144,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{ {
try try
{ {
ResultSet rs = __getResultSet(); return _trackResultSet(__getResultSet());
if (rs != null)
{
((IHikariResultSetProxy) rs)._setProxyStatement(this);
}
return rs;
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -138,13 +157,7 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
{ {
try try
{ {
ResultSet rs = __getGeneratedKeys(); return _trackResultSet(__getGeneratedKeys());
if (rs != null)
{
((IHikariResultSetProxy) rs)._setProxyStatement(this);
}
return rs;
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -184,31 +197,26 @@ public abstract class StatementProxy implements IHikariStatementProxy, Statement
public ResultSet __executeQuery(String sql) throws SQLException public ResultSet __executeQuery(String sql) throws SQLException
{ {
ResultSet resultSet = delegate.executeQuery(sql); return wrapResultSet(delegate.executeQuery(sql));
if (resultSet != null)
{
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
}
return resultSet;
} }
public ResultSet __getGeneratedKeys() throws SQLException public ResultSet __getGeneratedKeys() throws SQLException
{ {
ResultSet generatedKeys = delegate.getGeneratedKeys(); return wrapResultSet(delegate.getGeneratedKeys());
if (generatedKeys != null)
{
generatedKeys = PROXY_FACTORY.getProxyResultSet(this, generatedKeys);
}
return generatedKeys;
} }
public ResultSet __getResultSet() throws SQLException public ResultSet __getResultSet() throws SQLException
{ {
ResultSet resultSet = delegate.getResultSet(); return wrapResultSet(delegate.getResultSet());
}
protected ResultSet wrapResultSet(ResultSet resultSet)
{
if (resultSet != null) if (resultSet != null)
{ {
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet); resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
} }
return resultSet;
return resultSet;
} }
} }
Loading…
Cancel
Save