Remove instrumentation

pull/22/head
Brett Wooldridge 11 years ago
parent f84e02fb4b
commit e6dce5b73e

@ -1,169 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- For release: mvn release:perform -Darguments=-Dgpg.passphrase=PASSPHRASE -->
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-agent</artifactId>
<version>1.2.5-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>HikariCP-agent</name>
<description>Ultimate JDBC Connection Pool</description>
<url>https://github.com/brettwooldridge/HikariCP</url>
<organization>
<name>Zaxxer.com</name>
<url>https://github.com/brettwooldridge</url>
</organization>
<scm>
<connection>scm:git:git@github.com:brettwooldridge/HikariCP.git</connection>
<developerConnection>scm:git:git@github.com:brettwooldridge/HikariCP.git</developerConnection>
<url>git@github.com:brettwooldridge/HikariCP.git</url>
</scm>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>Brett Wooldridge</name>
<email>brett.wooldridge@gmail.com</email>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<type>maven-plugin</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.6.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.1-GA</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Name>HikariCP-agent</Bundle-Name>
<Export-Package>com.zaxxer.hikari.javassist</Export-Package>
<Import-Package>com.sun.tools.attach,javassist.*,javax.management,javax.sql,javax.sql.rowset,,javax.sql.rowset.serial,,javax.sql.rowset.spi,org.slf4j</Import-Package>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Agent-Class>com.zaxxer.hikari.javassist.HikariInstrumentationAgent</Agent-Class>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<!-- outputDirectory>/absolute/path/to/the/output/directory</outputDirectory>
<finalName>filename-of-generated-jar-file</finalName -->
<attach>true</attach>
</configuration>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<show>public</show>
<attach>true</attach>
<maxmemory>1024m</maxmemory>
</configuration>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

@ -1,45 +0,0 @@
/*
* Copyright (C) 2013 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari.javassist;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.util.Properties;
/**
* This class provides the "agentmain" method of the instrumentation agent.
*
* @author Brett Wooldridge
*/
public class HikariInstrumentationAgent
{
/**
* The method that is called when VirtualMachine.loadAgent() is invoked to register our
* class transformer.
*
* @param agentArgs arguments to pass to the agent
* @param instrumentation the virtual machine Instrumentation instance used to register our transformer
*/
public static void agentmain(String agentArgs, Instrumentation instrumentation)
{
Properties systemProperties = System.getProperties();
systemProperties.put("com.zaxxer.hikari.instrumentation", instrumentation);
ClassFileTransformer transformer = (ClassFileTransformer) systemProperties.get("com.zaxxer.hikari.transformer");
instrumentation.addTransformer(transformer, false);
}
}

@ -11,8 +11,7 @@ CLASSPATH=$CLASSPATH:~/.m2/repository/org/apache/tomcat/tomcat-jdbc/7.0.47/tomca
CLASSPATH=$CLASSPATH:~/.m2/repository/org/apache/tomcat/tomcat-juli/7.0.47/tomcat-juli-7.0.47.jar
CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/tools.jar
CLASSPATH=$CLASSPATH:./core/target/HikariCP-1.2.2-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:./agent/target/HikariCP-agent-1.2.2-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:./core/target/HikariCP-1.2.5-SNAPSHOT.jar
CLASSPATH=$CLASSPATH:./core/target/test-classes
java -classpath $CLASSPATH \

@ -167,7 +167,20 @@
<instructions>
<Bundle-Name>HikariCP</Bundle-Name>
<Export-Package>com.zaxxer.hikari</Export-Package>
<Import-Package>com.sun.tools.attach,javassist.*,javax.management,javax.sql,javax.sql.rowset,,javax.sql.rowset.serial,,javax.sql.rowset.spi,org.slf4j</Import-Package>
<Import-Package>
com.sun.tools.attach,javassist.*,
javax.management,
javax.sql,
javax.sql.rowset,
javax.sql.rowset.serial,
javax.sql.rowset.spi,
org.slf4j,
org.hibernate;resolution:=optional,
org.hibernate.cfg;resolution:=optional,
org.hibernate.engine.jdbc.connections.spi;resolution:=optional,
org.hibernate.service;resolution:=optional,
org.hibernate.service.spi;resolution:=optional
</Import-Package>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>

@ -31,7 +31,6 @@ import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.javassist.AgentRegistrationElf;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
import com.zaxxer.hikari.proxy.JavassistProxyFactoryFactory;
import com.zaxxer.hikari.util.PropertyBeanSetter;
@ -57,7 +56,6 @@ public final class HikariPool implements HikariPoolMBean
private final long leakDetectionThreshold;
private final boolean jdbc4ConnectionTest;
private final boolean isAutoCommit;
private final boolean delegationProxies;
private int transactionIsolation;
private final Timer houseKeepingTimer;
@ -85,13 +83,6 @@ public final class HikariPool implements HikariPoolMBean
String dsClassName = configuration.getDataSourceClassName();
try
{
String shadedCodexMapping = configuration.getShadedCodexMapping();
delegationProxies = !configuration.isUseInstrumentation() || !AgentRegistrationElf.loadTransformerAgent(dsClassName, shadedCodexMapping);
if (delegationProxies)
{
LOGGER.info("Using Javassist delegate-based proxies.");
}
Class<?> clazz = this.getClass().getClassLoader().loadClass(dsClassName);
this.dataSource = (DataSource) clazz.newInstance();
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
@ -139,7 +130,7 @@ public final class HikariPool implements HikariPoolMBean
idleConnectionCount.decrementAndGet();
final long maxLifetime = configuration.getMaxLifetime();
if (maxLifetime > 0 && start - connectionProxy._getCreationTime() > maxLifetime)
if (maxLifetime > 0 && start - connectionProxy.getCreationTime() > maxLifetime)
{
// Throw away the connection that has passed its lifetime, try again
closeConnection(connectionProxy);
@ -147,7 +138,7 @@ public final class HikariPool implements HikariPoolMBean
continue;
}
connectionProxy._unclose();
connectionProxy.unclose();
Connection connection = (Connection) connectionProxy;
if (!isConnectionAlive(connection, timeout))
@ -160,7 +151,7 @@ public final class HikariPool implements HikariPoolMBean
if (leakDetectionThreshold > 0)
{
connectionProxy._captureStack(leakDetectionThreshold, houseKeepingTimer);
connectionProxy.captureStack(leakDetectionThreshold, houseKeepingTimer);
}
connection.setAutoCommit(isAutoCommit);
@ -193,9 +184,9 @@ public final class HikariPool implements HikariPoolMBean
*/
public void releaseConnection(IHikariConnectionProxy connectionProxy)
{
if (!connectionProxy._isBrokenConnection())
if (!connectionProxy.isBrokenConnection())
{
connectionProxy._markLastAccess();
connectionProxy.markLastAccess();
idleConnectionCount.incrementAndGet();
idleConnections.put(connectionProxy);
@ -332,17 +323,7 @@ public final class HikariPool implements HikariPoolMBean
try
{
Connection connection = dataSource.getConnection();
IHikariConnectionProxy proxyConnection;
if (delegationProxies)
{
proxyConnection = (IHikariConnectionProxy) JavassistProxyFactoryFactory.getProxyFactory().getProxyConnection(connection);
}
else
{
proxyConnection = (IHikariConnectionProxy) connection;
}
proxyConnection._setParentPool(this);
IHikariConnectionProxy proxyConnection = (IHikariConnectionProxy) JavassistProxyFactoryFactory.getProxyFactory().getProxyConnection(this, connection);
boolean alive = isConnectionAlive((Connection) proxyConnection, configuration.getConnectionTimeout());
if (!alive)
@ -445,7 +426,7 @@ public final class HikariPool implements HikariPoolMBean
try
{
totalConnections.decrementAndGet();
connectionProxy.__close();
connectionProxy.realClose();
}
catch (SQLException e)
{
@ -477,9 +458,9 @@ public final class HikariPool implements HikariPoolMBean
idleConnectionCount.decrementAndGet();
if ((idleTimeout > 0 && now > connectionProxy._getLastAccess() + idleTimeout)
if ((idleTimeout > 0 && now > connectionProxy.getLastAccess() + idleTimeout)
||
(maxLifetime > 0 && now > connectionProxy._getCreationTime() + maxLifetime))
(maxLifetime > 0 && now > connectionProxy.getCreationTime() + maxLifetime))
{
closeConnection(connectionProxy);
}

@ -19,27 +19,11 @@ 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 CallableStatement).
*
* 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 CallableStatement implementation provided by the
* JDBC driver. In order to avoid name conflicts when injecting code into
* a driver class some of the fields and methods are prefixed with _ or __.
*
* Methods prefixed with __, like __executeQuery() are especially
* important because when we inject our 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.
* This is the proxy class for java.sql.CallableStatement.
*
* @author Brett Wooldridge
*/
public abstract class CallableStatementProxy extends PreparedStatementProxy implements IHikariStatementProxy, CallableStatement
public abstract class CallableStatementProxy extends PreparedStatementProxy implements CallableStatement
{
protected CallableStatementProxy(ConnectionProxy connection, CallableStatement statement)
{
@ -50,12 +34,4 @@ 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
// used when instrumentation is not available and "conventional" Javassist
// delegating proxies are used.
// ***********************************************************************
}

@ -28,49 +28,30 @@ import java.util.Timer;
import java.util.TimerTask;
import com.zaxxer.hikari.HikariPool;
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:
*
* 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 Connection implementation provided by the
* JDBC driver. In order to avoid name conflicts when injecting code into
* a driver class some of the fields and methods are prefixed with _ or __.
*
* Methods prefixed with __, like __createStatement() are especially
* important because when we inject our 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.
* This is the proxy class for java.sql.Connection.
*
* @author Brett Wooldridge
*/
public abstract class ConnectionProxy implements IHikariConnectionProxy
{
private static ProxyFactory PROXY_FACTORY;
@HikariInject protected static final Set<String> SQL_ERRORS;
@HikariInject protected ThreadLocal<Boolean> _isClosed;
private static final ProxyFactory PROXY_FACTORY;
@HikariInject protected ArrayList<IHikariStatementProxy> _openStatements;
@HikariInject protected HikariPool _parentPool;
private static final Set<String> SQL_ERRORS;
@HikariInject protected boolean _forceClose;
@HikariInject protected long _creationTime;
@HikariInject protected long _lastAccess;
protected final ArrayList<Statement> openStatements;
protected final HikariPool _parentPool;
protected final Connection delegate;
@HikariInject protected StackTraceElement[] _stackTrace;
@HikariInject protected TimerTask _leakTask;
protected final ThreadLocal<Boolean> isClosed;
protected boolean _forceClose;
protected long _creationTime;
protected long _lastAccess;
protected final Connection delegate;
protected StackTraceElement[] _stackTrace;
protected TimerTask _leakTask;
// static initializer
static
@ -82,64 +63,63 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
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();
PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
}
protected ConnectionProxy(Connection connection)
protected ConnectionProxy(HikariPool pool, Connection connection)
{
this._parentPool = pool;
this.delegate = connection;
// This is important when injecting in instrumentation mode. Do not change
// this name without also fixing the HikariClassTransformer.
__init();
openStatements = new ArrayList<Statement>(64);
_creationTime = _lastAccess = System.currentTimeMillis();
isClosed = new ThreadLocal<Boolean>() {
/** {@inheritDoc} */
@Override
protected Boolean initialValue()
{
return Boolean.FALSE;
}
};
}
@HikariInject
public void _unregisterStatement(Object statement)
public final void unregisterStatement(Object statement)
{
// If the connection is not closed. If it is closed, it means this is being
// called back as a result of the close() method below in which case we
// will clear the openStatements collection en mass.
if (!_isClosed.get())
if (!isClosed.get())
{
_openStatements.remove(statement);
openStatements.remove(statement);
}
}
@HikariInject
public final long _getCreationTime()
public final long getCreationTime()
{
return _creationTime;
}
@HikariInject
public final long _getLastAccess()
public final long getLastAccess()
{
return _lastAccess;
}
@HikariInject
public final void _markLastAccess()
public final void markLastAccess()
{
this._lastAccess = System.currentTimeMillis();
}
@HikariInject
public final void _setParentPool(HikariPool parentPool)
public final void unclose()
{
this._parentPool = parentPool;
isClosed.set(false);
}
@HikariInject
public final void _unclose()
public final void realClose() throws SQLException
{
_isClosed.set(false);
delegate.close();
}
@HikariInject
public final void _captureStack(long leakDetectionThreshold, Timer scheduler)
public final void captureStack(long leakDetectionThreshold, Timer scheduler)
{
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
_stackTrace = new StackTraceElement[trace.length - 4];
@ -149,14 +129,12 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
scheduler.schedule(_leakTask, leakDetectionThreshold);
}
@HikariInject
public final boolean _isBrokenConnection()
public final boolean isBrokenConnection()
{
return _forceClose;
}
@HikariInject
public final void _checkException(SQLException sqle)
public final void checkException(SQLException sqle)
{
String sqlState = sqle.getSQLState();
if (sqlState != null)
@ -165,41 +143,17 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
}
}
@HikariInject
protected void __init()
protected final void checkClosed() throws SQLException
{
if (_openStatements == null)
{
_openStatements = new ArrayList<IHikariStatementProxy>(64);
_creationTime = _lastAccess = System.currentTimeMillis();
_isClosed = new ThreadLocal<Boolean>() {
/** {@inheritDoc} */
@Override
protected Boolean initialValue()
{
return Boolean.FALSE;
}
};
}
}
@HikariInject
protected final void _checkClosed() throws SQLException
{
if (_isClosed.get())
if (isClosed.get())
{
throw new SQLException("Connection is closed");
}
}
@HikariInject
protected final <T extends IHikariStatementProxy> T _trackStatement(T statement)
protected final <T extends Statement> T trackStatement(T statement)
{
if (statement._getConnectionProxy() == null)
{
statement._setConnectionProxy(this);
_openStatements.add(statement);
}
openStatements.add(statement);
return statement;
}
@ -208,7 +162,7 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
// "Overridden" java.sql.Connection Methods
// **********************************************************************
@HikariOverride
/** {@inheritDoc} */
public void close() throws SQLException
{
if (!isClosed())
@ -222,10 +176,10 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
try
{
// Faster than an iterator most times
final int length = _openStatements.size();
final int length = openStatements.size();
for (int i = 0; i < length; i++)
{
_openStatements.get(i).close();
openStatements.get(i).close();
}
if (!getAutoCommit())
@ -235,328 +189,283 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
finally
{
_isClosed.set(true);
_openStatements.clear();
isClosed.set(true);
openStatements.clear();
_parentPool.releaseConnection(this);
}
}
}
@HikariOverride
/** {@inheritDoc} */
public boolean isClosed() throws SQLException
{
return _isClosed.get();
return isClosed.get();
}
@HikariOverride
/** {@inheritDoc} */
public Statement createStatement() throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __createStatement();
return _trackStatement(statement);
return trackStatement(__createStatement());
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __createStatement(resultSetType, resultSetConcurrency);
return _trackStatement(statement);
return trackStatement(__createStatement(resultSetType, resultSetConcurrency));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
return _trackStatement(statement);
return trackStatement(__createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public CallableStatement prepareCall(String sql) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareCall(sql);
return (CallableStatement) _trackStatement(statement);
return trackStatement(__prepareCall(sql));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareCall(sql, resultSetType, resultSetConcurrency);
return (CallableStatement) _trackStatement(statement);
return trackStatement(__prepareCall(sql, resultSetType, resultSetConcurrency));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
return (CallableStatement) _trackStatement(statement);
return trackStatement(__prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql, autoGeneratedKeys);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql, autoGeneratedKeys));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql, resultSetType, resultSetConcurrency);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql, resultSetType, resultSetConcurrency));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql, columnIndexes);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql, columnIndexes));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException
{
_checkClosed();
checkClosed();
try
{
IHikariStatementProxy statement = (IHikariStatementProxy) __prepareStatement(sql, columnNames);
return (PreparedStatement) _trackStatement(statement);
return trackStatement(__prepareStatement(sql, columnNames));
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public boolean isValid(int timeout) throws SQLException
{
if (_isClosed.get())
if (isClosed.get())
{
return false;
}
try
{
return __isValid(timeout);
return delegate.isValid(timeout);
}
catch (SQLException e)
{
_checkException(e);
checkException(e);
throw e;
}
}
// ***********************************************************************
// These methods contain code we do not want injected into the actual
// java.sql.Connection implementation class. These methods are only
// used when instrumentation is not available and "conventional" Javassist
// delegating proxies are used.
// ***********************************************************************
private static void __static()
{
if (PROXY_FACTORY == null)
{
PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
}
}
public final void __close() throws SQLException
{
delegate.close();
}
public final boolean __isValid(int timeout) throws SQLException
{
return delegate.isValid(timeout);
}
// **********************************************************************
// Private Methods
// **********************************************************************
public final Statement __createStatement() throws SQLException
private final Statement __createStatement() throws SQLException
{
return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement());
}
public final Statement __createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
private final Statement __createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
{
return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency));
}
public final Statement __createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
private final Statement __createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
}
public final CallableStatement __prepareCall(String sql) throws SQLException
private final CallableStatement __prepareCall(String sql) throws SQLException
{
return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql));
}
public final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
private final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency));
}
public final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
private final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
public final PreparedStatement __prepareStatement(String sql) throws SQLException
private final PreparedStatement __prepareStatement(String sql) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql));
}
public final PreparedStatement __prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
private final PreparedStatement __prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, autoGeneratedKeys));
}
public final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
private final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency));
}
public final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
private final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
public final PreparedStatement __prepareStatement(String sql, int[] columnIndexes) throws SQLException
private final PreparedStatement __prepareStatement(String sql, int[] columnIndexes) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnIndexes));
}
public final PreparedStatement __prepareStatement(String sql, String[] columnNames) throws SQLException
private final PreparedStatement __prepareStatement(String sql, String[] columnNames) throws SQLException
{
return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames));
}

@ -20,34 +20,28 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.util.Timer;
import com.zaxxer.hikari.HikariPool;
/**
*
* @author Brett Wooldridge
*/
public interface IHikariConnectionProxy extends Connection
{
void _unclose();
void __close() throws SQLException;
void _unregisterStatement(Object statement);
void unclose();
void _checkException(SQLException sqle);
void realClose() throws SQLException;
boolean _isBrokenConnection();
void unregisterStatement(Object statement);
long _getCreationTime();
void checkException(SQLException sqle);
long _getLastAccess();
boolean isBrokenConnection();
void _markLastAccess();
long getCreationTime();
void _setParentPool(HikariPool parentPool);
long getLastAccess();
Connection getDelegate();
void markLastAccess();
/* Leak Detection API */
void _captureStack(long leakThreshold, Timer houseKeepingTimer);
void captureStack(long leakThreshold, Timer houseKeepingTimer);
}

@ -72,9 +72,9 @@ public final class JavassistProxyFactoryFactory
try
{
String methodBody = "{ _checkClosed(); try { return ((cast) delegate).method($$); } catch (SQLException e) { _checkException(e); throw e;} }";
String methodBody = "{ checkClosed(); try { return ((cast) delegate).method($$); } catch (SQLException e) { checkException(e); throw e;} }";
generateProxyClass(Connection.class, ConnectionProxy.class, methodBody);
methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { _checkException(e); throw e;} }";
methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { checkException(e); throw e;} }";
generateProxyClass(Statement.class, StatementProxy.class, methodBody);
generateProxyClass(CallableStatement.class, CallableStatementProxy.class, methodBody);
generateProxyClass(PreparedStatement.class, PreparedStatementProxy.class, methodBody);

@ -20,30 +20,12 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
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 PreparedStatement).
*
* 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 when injecting code into
* a driver class some of the fields and methods are prefixed with _ or __.
*
* Methods prefixed with __, like __executeQuery() are especially
* important because when we inject our 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.
* This is the proxy class for java.sql.PreparedStatement.
*
* @author Brett Wooldridge
*/
public abstract class PreparedStatementProxy extends StatementProxy implements IHikariStatementProxy, PreparedStatement
public abstract class PreparedStatementProxy extends StatementProxy implements PreparedStatement
{
protected PreparedStatementProxy(ConnectionProxy connection, PreparedStatement statement)
{
@ -54,30 +36,17 @@ public abstract class PreparedStatementProxy extends StatementProxy implements I
// Overridden java.sql.PreparedStatement Methods
// **********************************************************************
@HikariOverride
/** {@inheritDoc} */
public ResultSet executeQuery() throws SQLException
{
try
{
return _trackResultSet(__executeQuery());
return wrapResultSet(((PreparedStatement) delegate).executeQuery());
}
catch (SQLException e)
{
_connection._checkException(e);
connection.checkException(e);
throw e;
}
}
// ***********************************************************************
// These methods contain code we do not want injected into the actual
// java.sql.Connection implementation class. These methods are only
// used when instrumentation is not available and "conventional" Javassist
// delegating proxies are used.
// ***********************************************************************
public ResultSet __executeQuery() throws SQLException
{
ResultSet resultSet = ((PreparedStatement) delegate).executeQuery();
return wrapResultSet(resultSet);
}
}

@ -22,12 +22,17 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.zaxxer.hikari.HikariPool;
/**
* This class defines the interface for generating proxies, the
* real (concrete) class is actually generated by Javassist.
*
* @author Brett Wooldridge
*/
public abstract class ProxyFactory
{
/* Classes should use ProxyFactory.INSTANCE to access the factory */
// final ProxyFactory INSTANCE = Initializer.initialize();
public abstract Connection getProxyConnection(Connection connection);
public abstract Connection getProxyConnection(HikariPool pool, Connection connection);
public abstract Statement getProxyStatement(ConnectionProxy connection, Statement statement);
@ -35,30 +40,5 @@ public abstract class ProxyFactory
public abstract PreparedStatement getProxyPreparedStatement(ConnectionProxy connection, PreparedStatement statement);
public abstract ResultSet getProxyResultSet(IHikariStatementProxy statement, ResultSet resultSet);
/**************************************************************************
*
* Initializer class used to initialize the proxy factory.
*/
// class Initializer
// {
// private static ProxyFactory initialize()
// {
// try
// {
// ClassLoader classLoader = Initializer.class.getClassLoader();
// classLoader.loadClass("javassist.CtClass");
// Class<?> proxyFactoryClass = classLoader.loadClass("com.zaxxer.hikari.proxy.JavassistProxyFactoryFactory");
// Object factoryFactory = proxyFactoryClass.newInstance();
// Method getter = factoryFactory.getClass().getMethod("getProxyFactory");
// return (ProxyFactory) getter.invoke(factoryFactory);
// }
// catch (Exception ex)
// {
// LoggerFactory.getLogger(ProxyFactory.class).error("Error initializing ProxyFactory", ex);
// throw new RuntimeException("Error initializing ProxyFactory", ex);
// }
// }
// }
public abstract ResultSet getProxyResultSet(StatementProxy statement, ResultSet resultSet);
}

@ -20,47 +20,28 @@ import java.sql.ResultSet;
import java.sql.SQLException;
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 ResultSet).
*
* 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 when injecting code into
* a driver class some of the fields and methods are prefixed with _ or __.
* This is the proxy class for java.sql.ResultSet.
*
* @author Brett Wooldridge
*/
public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet
public abstract class ResultSetProxy implements ResultSet
{
@HikariInject protected IHikariStatementProxy _statement;
private final StatementProxy statement;
protected final ResultSet delegate;
protected ResultSetProxy(IHikariStatementProxy statement, ResultSet resultSet)
protected ResultSetProxy(StatementProxy statement, ResultSet resultSet)
{
this._statement = statement;
this.statement = statement;
this.delegate = resultSet;
}
@HikariInject
public final void _checkException(SQLException e)
public final void checkException(SQLException e)
{
_statement._checkException(e);
statement.checkException(e);
}
@HikariInject
public void _setProxyStatement(IHikariStatementProxy statement)
{
this._statement = statement;
}
// **********************************************************************
// Overridden java.sql.ResultSet Methods
// other methods are injected
@ -68,6 +49,6 @@ public abstract class ResultSetProxy implements IHikariResultSetProxy, ResultSet
public Statement getStatement() throws SQLException
{
return (Statement) _statement;
return (Statement) statement;
}
}

@ -21,206 +21,118 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
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 Statement).
*
* 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 when injecting code into
* a driver class some of the fields and methods are prefixed with _ or __.
*
* Methods prefixed with __, like __executeQuery() are especially
* important because when we inject our 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.
* This is the proxy class for java.sql.Statement.
*
* @author Brett Wooldridge
*/
public abstract class StatementProxy implements IHikariStatementProxy, Statement
public abstract class StatementProxy implements Statement
{
protected static ProxyFactory PROXY_FACTORY;
protected static final ProxyFactory PROXY_FACTORY;
@HikariInject protected IHikariConnectionProxy _connection;
protected final IHikariConnectionProxy connection;
@HikariInject protected boolean _isClosed;
protected boolean isClosed;
protected final Statement delegate;
static
{
// This is important when injecting in instrumentation mode. Do not change
// this name without also fixing the HikariClassTransformer.
__static();
PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
}
protected StatementProxy(IHikariConnectionProxy connection, Statement statement)
{
this._connection = connection;
this.connection = connection;
this.delegate = statement;
}
@HikariInject
public void _setConnectionProxy(IHikariConnectionProxy connection)
{
this._connection = connection;
}
@HikariInject
public IHikariConnectionProxy _getConnectionProxy()
{
return _connection;
}
@HikariInject
public final void _checkException(SQLException e)
{
_connection._checkException(e);
}
@HikariInject
public void _releaseResultSet(IHikariResultSetProxy resultSet)
protected final void checkException(SQLException e)
{
connection.checkException(e);
}
@HikariInject
protected <T extends ResultSet> T _trackResultSet(T resultSet)
protected final ResultSet wrapResultSet(ResultSet resultSet)
{
if (resultSet != null)
{
((IHikariResultSetProxy) resultSet)._setProxyStatement(this);
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
}
return resultSet;
return resultSet;
}
// **********************************************************************
// Overridden java.sql.Statement Methods
// **********************************************************************
@HikariOverride
/** {@inheritDoc} */
public void close() throws SQLException
{
if (_isClosed)
if (isClosed)
{
return;
}
_isClosed = true;
_connection._unregisterStatement(this);
isClosed = true;
connection.unregisterStatement(this);
try
{
__close();
delegate.close();
}
catch (SQLException e)
{
_connection._checkException(e);
connection.checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public ResultSet executeQuery(String sql) throws SQLException
{
try
{
return _trackResultSet(__executeQuery(sql));
return wrapResultSet(delegate.executeQuery(sql));
}
catch (SQLException e)
{
_connection._checkException(e);
connection.checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public ResultSet getResultSet() throws SQLException
{
try
{
return _trackResultSet(__getResultSet());
return wrapResultSet(delegate.getResultSet());
}
catch (SQLException e)
{
_connection._checkException(e);
connection.checkException(e);
throw e;
}
}
@HikariOverride
/** {@inheritDoc} */
public ResultSet getGeneratedKeys() throws SQLException
{
try
{
return _trackResultSet(__getGeneratedKeys());
return wrapResultSet(delegate.getGeneratedKeys());
}
catch (SQLException e)
{
_connection._checkException(e);
connection.checkException(e);
throw e;
}
}
/** {@inheritDoc} */
public Connection getConnection() throws SQLException
{
return (Connection) _connection;
}
// ***********************************************************************
// These methods contain code we do not want injected into the actual
// java.sql.Connection implementation class. These methods are only
// used when instrumentation is not available and "conventional" Javassist
// delegating proxies are used.
// ***********************************************************************
private static void __static()
{
if (PROXY_FACTORY == null)
{
PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
}
}
public void __close() throws SQLException
{
if (delegate.isClosed())
{
return;
}
delegate.close();
}
public ResultSet __executeQuery(String sql) throws SQLException
{
return wrapResultSet(delegate.executeQuery(sql));
}
public ResultSet __getGeneratedKeys() throws SQLException
{
return wrapResultSet(delegate.getGeneratedKeys());
}
public ResultSet __getResultSet() throws SQLException
{
return wrapResultSet(delegate.getResultSet());
}
protected ResultSet wrapResultSet(ResultSet resultSet)
{
if (resultSet != null)
{
resultSet = PROXY_FACTORY.getProxyResultSet(this, resultSet);
}
return resultSet;
return (Connection) connection;
}
}

@ -49,7 +49,7 @@
<modules>
<module>core</module>
<module>agent</module>
</modules>
<dependencyManagement>

Loading…
Cancel
Save