More work on codex based instrumentation.

pull/3/merge
Brett Wooldridge 11 years ago
parent 7c640a6069
commit 28cbc5048f

@ -80,15 +80,15 @@ public final class HikariPool implements HikariPoolMBean
try
{
Class<?> clazz = ClassLoaderUtils.loadClass(configuration.getDataSourceClassName());
this.dataSource = (DataSource) clazz.newInstance();
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
delegationProxies = !AgentRegistrationElf.loadTransformerAgent(configuration.getDataSourceClassName());
if (delegationProxies)
{
LOGGER.info("Falling back to Javassist delegate-based proxies.");
}
Class<?> clazz = ClassLoaderUtils.loadClass(configuration.getDataSourceClassName());
this.dataSource = (DataSource) clazz.newInstance();
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
}
catch (Exception e)
{

@ -50,7 +50,6 @@ public class AgentRegistrationElf
{
Properties systemProperties = System.getProperties();
systemProperties.put("com.zaxxer.hikari.classloader", AgentRegistrationElf.class.getClassLoader());
HikariClassTransformer transformer = new HikariClassTransformer();
systemProperties.put("com.zaxxer.hikari.transformer", transformer);
@ -59,19 +58,20 @@ public class AgentRegistrationElf
LOGGER.info("Successfully loaded instrumentation agent. Scanning classes...");
HikariClassScanner scanner = new HikariClassScanner(transformer);
scanner.scanClasses(dsClassName);
return true;
return scanner.scanClasses(dsClassName);
}
catch (Exception e)
{
LOGGER.warn("Instrumentation agent could not be loaded. Please report at http://github.com/brettwooldridge/HikariCP.", e);
return false;
}
// finally
// {
// unregisterInstrumenation();
// }
finally
{
if (HikariInstrumentationAgent.unregisterInstrumenation())
{
LOGGER.info("Unloaded instrumentation agent.");
}
}
}
/**

@ -17,25 +17,11 @@
package com.zaxxer.hikari.javassist;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javassist.bytecode.ClassFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,29 +36,12 @@ public class HikariClassScanner
{
private static final Logger LOGGER = LoggerFactory.getLogger(HikariClassScanner.class);
private static final LinkedHashMap<String, Boolean> completionMap;
private final HashMap<String, ClassFile> instrumentableClasses;
// Static initializer
static
{
completionMap = new LinkedHashMap<>();
completionMap.put("java.sql.Connection", false);
completionMap.put("java.sql.ResultSet", false);
completionMap.put("java.sql.CallableStatement", false);
completionMap.put("java.sql.PreparedStatement", false);
completionMap.put("java.sql.Statement", false);
}
private HikariClassTransformer transformer;
private String sniffPackage;
private Properties codex;
public HikariClassScanner(HikariClassTransformer transformer)
{
instrumentableClasses = new HashMap<>();
this.transformer = transformer;
}
@ -93,7 +62,7 @@ public class HikariClassScanner
HashSet<String> hash = (HashSet<String>) codex.get(dsClassName);
if (hash == null)
{
LOGGER.warn("DataSource {} not found in instrumentation codex. Please report at http://github.com/brettwooldridge/HikariCP.", dsClassName);
LOGGER.warn("DataSource {} not found in the instrumentation codex. Please report at http://github.com/brettwooldridge/HikariCP.", dsClassName);
LOGGER.info("Using delegation instead of instrumentation");
return false;
}

@ -172,9 +172,9 @@ public class HikariClassTransformer implements ClassFileTransformer
copyFields(proxy, target);
copyMethods(proxy, target, classFile);
for (CtConstructor constructor : target.getConstructors())
for (CtConstructor constructor : target.getDeclaredConstructors())
{
constructor.insertAfter("__init();");
constructor.insertBeforeBody("__init();");
}
mergeClassInitializers(proxy, target, classFile);
@ -197,7 +197,7 @@ public class HikariClassTransformer implements ClassFileTransformer
for (CtConstructor constructor : target.getDeclaredConstructors())
{
constructor.insertAfter("__init();");
constructor.insertBeforeBody("__init();");
}
return target.toBytecode();
@ -261,7 +261,6 @@ public class HikariClassTransformer implements ClassFileTransformer
private void copyMethods(CtClass srcClass, CtClass targetClass, ClassFile targetClassFile) throws Exception
{
CtMethod[] destMethods = targetClass.getMethods();
ConstPool constPool = targetClassFile.getConstPool();
for (CtMethod method : srcClass.getDeclaredMethods())
@ -271,20 +270,6 @@ public class HikariClassTransformer implements ClassFileTransformer
continue;
}
if (targetClassFile.getMethod(method.getName()) != null) // maybe we have a name collision
{
String signature = method.getSignature();
for (CtMethod destMethod : destMethods)
{
if (destMethod.getName().equals(method.getName()) && destMethod.getSignature().equals(signature))
{
LOGGER.debug("Rename method {}.{} to __{}", targetClass.getSimpleName(), destMethod.getName(), destMethod.getName());
destMethod.setName("__" + destMethod.getName());
break;
}
}
}
CtMethod copy = CtNewMethod.copy(method, targetClass, null);
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("com.zaxxer.hikari.javassist.HikariInject", constPool);

@ -26,8 +26,6 @@ import java.util.Properties;
*/
public class HikariInstrumentationAgent
{
private static Instrumentation ourInstrumentation;
/**
* The method that is called when VirtualMachine.loadAgent() is invoked to register our
* class transformer.
@ -37,11 +35,29 @@ public class HikariInstrumentationAgent
*/
public static void agentmain(String agentArgs, Instrumentation instrumentation)
{
ourInstrumentation = 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);
}
static boolean unregisterInstrumenation()
{
boolean unregistered = false;
Properties systemProperties = System.getProperties();
Instrumentation instrumentation = (Instrumentation) systemProperties.get("com.zaxxer.hikari.instrumentation");
if (instrumentation != null)
{
ClassFileTransformer transformer = (ClassFileTransformer) systemProperties.get("com.zaxxer.hikari.transformer");
instrumentation.removeTransformer(transformer);
unregistered = true;
}
systemProperties.remove("com.zaxxer.hikari.instrumentation");
systemProperties.remove("com.zaxxer.hikari.transformer");
ourInstrumentation.addTransformer(transformer, false);
return unregistered;
}
}

@ -58,8 +58,6 @@ public class ConnectionProxy implements IHikariConnectionProxy
@HikariInject protected ArrayList<Statement> _openStatements;
@HikariInject protected HikariPool _parentPool;
protected final Connection delegate;
@HikariInject protected volatile boolean _forceClose;
@HikariInject protected long _creationTime;
@HikariInject protected long _lastAccess;
@ -67,6 +65,8 @@ public class ConnectionProxy implements IHikariConnectionProxy
@HikariInject protected StackTraceElement[] _stackTrace;
@HikariInject protected TimerTask _leakTask;
protected final Connection delegate;
// static initializer
static
{
@ -157,10 +157,13 @@ public class ConnectionProxy implements IHikariConnectionProxy
@HikariInject
protected void __init()
{
if (_openStatements == null)
{
_openStatements = new ArrayList<Statement>(64);
_creationTime = _lastAccess = System.currentTimeMillis();
}
}
@HikariInject
protected void _checkClosed() throws SQLException
@ -194,8 +197,9 @@ public class ConnectionProxy implements IHikariConnectionProxy
try
{
// Faster than an iterator
for (int i = _openStatements.size() - 1; i >= 0; i--)
// Faster than an iterator most times
final int length = _openStatements.size();
for (int i = 0; i < length; i++)
{
_openStatements.get(i).close();
}

@ -84,5 +84,19 @@ mysql.subResultSet=com.mysql.jdbc.JDBC4ResultSet
mysql.subResultSet=com.mysql.jdbc.UpdatableResultSet
mysql.subResultSet=com.mysql.jdbc.JDBC4UpdatableResultSet
# ------ Driver v0.0.0 ----------------------------------------------------------
# ------ HikariCP Testing v0.0.0 ----------------------------------------------------------
#
com.zaxxer.hikari.mocks.StubDataSource=hikari
hikari.baseConnection=com.zaxxer.hikari.mocks.StubBaseConnection
hikari.subConnection=com.zaxxer.hikari.mocks.StubConnection
hikari.baseStatement=com.zaxxer.hikari.mocks.StubStatement
hikari.subPreparedStatement=com.zaxxer.hikari.mocks.StubPreparedStatement
hikari.baseResultSet=com.zaxxer.hikari.mocks.StubResultSet
com.zaxxer.hikari.performance.StubDataSource=hikari-perf
hikari-perf.baseConnection=com.zaxxer.hikari.performance.StubConnection
hikari-perf.baseStatement=com.zaxxer.hikari.performance.StubStatement
hikari-perf.subPreparedStatement=com.zaxxer.hikari.performance.StubPreparedStatement
hikari-perf.baseResultSet=com.zaxxer.hikari.performance.StubResultSet

@ -63,7 +63,7 @@ public class StubResultSet implements ResultSet
/** {@inheritDoc} */
public boolean next() throws SQLException
{
return (counter < 10);
return (counter > 100000);
}
/** {@inheritDoc} */

@ -76,12 +76,10 @@ public class Benchmark1
System.out.println(" Warming up JIT");
benchmarks.startMixedBench(100, 10000);
System.out.println(" MixedBench Final Timing Runs");
long elapsed = 0;
elapsed += benchmarks.startMixedBench(THREADS, 1000);
elapsed += benchmarks.startMixedBench(THREADS, 1000);
elapsed += benchmarks.startMixedBench(THREADS, 1000);
elapsed += benchmarks.startMixedBench(THREADS, 1000);
System.out.printf("Elapsed time for timing runs (excluding thread start): %dms\n", TimeUnit.NANOSECONDS.toMillis(elapsed));
benchmarks.startMixedBench(THREADS, 1000);
benchmarks.startMixedBench(THREADS, 1000);
benchmarks.startMixedBench(THREADS, 1000);
benchmarks.startMixedBench(THREADS, 1000);
System.out.println("\nBoneBench");
System.out.println(" Warming up JIT");
@ -168,7 +166,7 @@ public class Benchmark1
config.setConnectionTimeout(8000);
config.setIdleTimeout(TimeUnit.MINUTES.toMillis(30));
config.setJdbc4ConnectionTest(true);
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setDataSourceClassName("com.zaxxer.hikari.performance.StubDataSource");
HikariDataSource ds = new HikariDataSource(config);
return ds;
@ -178,7 +176,7 @@ public class Benchmark1
{
try
{
Class.forName("com.zaxxer.hikari.mocks.StubDriver");
Class.forName("com.zaxxer.hikari.performance.StubDriver");
}
catch (ClassNotFoundException e)
{
@ -205,7 +203,7 @@ public class Benchmark1
private DataSource setupDbPool()
{
DBPoolDataSource ds = new DBPoolDataSource();
ds.setDriverClassName("com.zaxxer.hikari.mocks.StubDriver");
ds.setDriverClassName("com.zaxxer.hikari.performance.StubDriver");
ds.setUrl("jdbc:stub");
ds.setMinPool(POOL_MAX / 2);
ds.setMaxPool(POOL_MAX);
@ -222,7 +220,7 @@ public class Benchmark1
try
{
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "com.zaxxer.hikari.mocks.StubDriver" );
cpds.setDriverClass( "com.zaxxer.hikari.performance.StubDriver" );
cpds.setJdbcUrl( "jdbc:stub" );
cpds.setMinPoolSize(POOL_MAX / 2);
cpds.setMaxPoolSize(POOL_MAX);

@ -117,7 +117,7 @@ public class StubResultSet implements ResultSet
/** {@inheritDoc} */
public float getFloat(int columnIndex) throws SQLException
{
throw new SQLException("No reason", "08999");
return 0;
}
/** {@inheritDoc} */

@ -45,8 +45,7 @@ public class StubStatement implements Statement
/** {@inheritDoc} */
public ResultSet executeQuery(String sql) throws SQLException
{
StubResultSet resultSet = new StubResultSet();
return resultSet;
return new StubResultSet();
}
/** {@inheritDoc} */

Loading…
Cancel
Save