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 try
{ {
Class<?> clazz = ClassLoaderUtils.loadClass(configuration.getDataSourceClassName());
this.dataSource = (DataSource) clazz.newInstance();
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
delegationProxies = !AgentRegistrationElf.loadTransformerAgent(configuration.getDataSourceClassName()); delegationProxies = !AgentRegistrationElf.loadTransformerAgent(configuration.getDataSourceClassName());
if (delegationProxies) if (delegationProxies)
{ {
LOGGER.info("Falling back to Javassist delegate-based proxies."); 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) catch (Exception e)
{ {

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

@ -17,25 +17,11 @@
package com.zaxxer.hikari.javassist; package com.zaxxer.hikari.javassist;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; 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.HashSet;
import java.util.LinkedHashMap;
import java.util.Properties; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -50,29 +36,12 @@ public class HikariClassScanner
{ {
private static final Logger LOGGER = LoggerFactory.getLogger(HikariClassScanner.class); 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 HikariClassTransformer transformer;
private String sniffPackage;
private Properties codex; private Properties codex;
public HikariClassScanner(HikariClassTransformer transformer) public HikariClassScanner(HikariClassTransformer transformer)
{ {
instrumentableClasses = new HashMap<>();
this.transformer = transformer; this.transformer = transformer;
} }
@ -93,7 +62,7 @@ public class HikariClassScanner
HashSet<String> hash = (HashSet<String>) codex.get(dsClassName); HashSet<String> hash = (HashSet<String>) codex.get(dsClassName);
if (hash == null) 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"); LOGGER.info("Using delegation instead of instrumentation");
return false; return false;
} }

@ -172,9 +172,9 @@ public class HikariClassTransformer implements ClassFileTransformer
copyFields(proxy, target); copyFields(proxy, target);
copyMethods(proxy, target, classFile); copyMethods(proxy, target, classFile);
for (CtConstructor constructor : target.getConstructors()) for (CtConstructor constructor : target.getDeclaredConstructors())
{ {
constructor.insertAfter("__init();"); constructor.insertBeforeBody("__init();");
} }
mergeClassInitializers(proxy, target, classFile); mergeClassInitializers(proxy, target, classFile);
@ -197,7 +197,7 @@ public class HikariClassTransformer implements ClassFileTransformer
for (CtConstructor constructor : target.getDeclaredConstructors()) for (CtConstructor constructor : target.getDeclaredConstructors())
{ {
constructor.insertAfter("__init();"); constructor.insertBeforeBody("__init();");
} }
return target.toBytecode(); return target.toBytecode();
@ -261,7 +261,6 @@ public class HikariClassTransformer implements ClassFileTransformer
private void copyMethods(CtClass srcClass, CtClass targetClass, ClassFile targetClassFile) throws Exception private void copyMethods(CtClass srcClass, CtClass targetClass, ClassFile targetClassFile) throws Exception
{ {
CtMethod[] destMethods = targetClass.getMethods();
ConstPool constPool = targetClassFile.getConstPool(); ConstPool constPool = targetClassFile.getConstPool();
for (CtMethod method : srcClass.getDeclaredMethods()) for (CtMethod method : srcClass.getDeclaredMethods())
@ -271,20 +270,6 @@ public class HikariClassTransformer implements ClassFileTransformer
continue; 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); CtMethod copy = CtNewMethod.copy(method, targetClass, null);
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("com.zaxxer.hikari.javassist.HikariInject", constPool); Annotation annotation = new Annotation("com.zaxxer.hikari.javassist.HikariInject", constPool);

@ -26,8 +26,6 @@ import java.util.Properties;
*/ */
public class HikariInstrumentationAgent public class HikariInstrumentationAgent
{ {
private static Instrumentation ourInstrumentation;
/** /**
* The method that is called when VirtualMachine.loadAgent() is invoked to register our * The method that is called when VirtualMachine.loadAgent() is invoked to register our
* class transformer. * class transformer.
@ -37,11 +35,29 @@ public class HikariInstrumentationAgent
*/ */
public static void agentmain(String agentArgs, Instrumentation instrumentation) public static void agentmain(String agentArgs, Instrumentation instrumentation)
{ {
ourInstrumentation = instrumentation;
Properties systemProperties = System.getProperties(); Properties systemProperties = System.getProperties();
systemProperties.put("com.zaxxer.hikari.instrumentation", instrumentation);
ClassFileTransformer transformer = (ClassFileTransformer) systemProperties.get("com.zaxxer.hikari.transformer"); 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 ArrayList<Statement> _openStatements;
@HikariInject protected HikariPool _parentPool; @HikariInject protected HikariPool _parentPool;
protected final Connection delegate;
@HikariInject protected volatile boolean _forceClose; @HikariInject protected volatile boolean _forceClose;
@HikariInject protected long _creationTime; @HikariInject protected long _creationTime;
@HikariInject protected long _lastAccess; @HikariInject protected long _lastAccess;
@ -67,6 +65,8 @@ public class ConnectionProxy implements IHikariConnectionProxy
@HikariInject protected StackTraceElement[] _stackTrace; @HikariInject protected StackTraceElement[] _stackTrace;
@HikariInject protected TimerTask _leakTask; @HikariInject protected TimerTask _leakTask;
protected final Connection delegate;
// static initializer // static initializer
static static
{ {
@ -158,8 +158,11 @@ public class ConnectionProxy implements IHikariConnectionProxy
@HikariInject @HikariInject
protected void __init() protected void __init()
{ {
_openStatements = new ArrayList<Statement>(64); if (_openStatements == null)
_creationTime = _lastAccess = System.currentTimeMillis(); {
_openStatements = new ArrayList<Statement>(64);
_creationTime = _lastAccess = System.currentTimeMillis();
}
} }
@HikariInject @HikariInject
@ -194,8 +197,9 @@ public class ConnectionProxy implements IHikariConnectionProxy
try try
{ {
// Faster than an iterator // Faster than an iterator most times
for (int i = _openStatements.size() - 1; i >= 0; i--) final int length = _openStatements.size();
for (int i = 0; i < length; i++)
{ {
_openStatements.get(i).close(); _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.UpdatableResultSet
mysql.subResultSet=com.mysql.jdbc.JDBC4UpdatableResultSet 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} */ /** {@inheritDoc} */
public boolean next() throws SQLException public boolean next() throws SQLException
{ {
return (counter < 10); return (counter > 100000);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

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

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

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

Loading…
Cancel
Save