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;
/**
* 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

@ -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, <i>except</i> for PROXY_FACTORY
* and 'delegate' are also injected. In order to avoid name conflicts the
* fields of this class have slightly unconventional names.
* the &amp;HikariInject and &amp;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
// **********************************************************************

@ -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());

@ -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 &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
*/
@ -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);
}
}

@ -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 &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
*/
public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet

@ -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 &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
*/
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 extends ResultSet> 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;
}
}
Loading…
Cancel
Save