Test for javassist code generation.

pull/977/head
Brett Wooldridge 7 years ago
parent 171ddd5523
commit f8cc907f24

@ -55,6 +55,7 @@ import javassist.bytecode.ClassFile;
public final class JavassistProxyFactory
{
private static ClassPool classPool;
private static String genDirectory = "";
public static void main(String... args)
{
@ -62,6 +63,10 @@ public final class JavassistProxyFactory
classPool.importPackage("java.sql");
classPool.appendClassPath(new LoaderClassPath(JavassistProxyFactory.class.getClassLoader()));
if (args.length > 0) {
genDirectory = args[0];
}
try {
// Cast is not needed for these
String methodBody = "{ try { return delegate.method($$); } catch (SQLException e) { throw checkException(e); } }";
@ -110,7 +115,7 @@ public final class JavassistProxyFactory
}
}
proxyCt.writeFile("target/classes");
proxyCt.writeFile(genDirectory + "target/classes");
}
/**
@ -189,8 +194,8 @@ public final class JavassistProxyFactory
}
}
targetCt.getClassFile().setMajorVersion(ClassFile.JAVA_7);
targetCt.writeFile("target/classes");
targetCt.getClassFile().setMajorVersion(ClassFile.JAVA_8);
targetCt.writeFile(genDirectory + "target/classes");
}
private static boolean isThrowsSqlException(CtMethod method)

@ -16,8 +16,11 @@
package com.zaxxer.hikari.pool;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.sql.Connection;
import org.apache.logging.log4j.Level;
@ -177,4 +180,35 @@ public final class TestElf
stream.println(event.getMessage().getFormattedMessage());
}
}
public static class FauxWebClassLoader extends ClassLoader
{
static final byte[] classBytes = new byte[16_000];
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
if (name.startsWith("java") || name.startsWith("org")) {
return super.loadClass(name, true);
}
final String resourceName = "/" + name.replace('.', '/') + ".class";
final URL resource = this.getClass().getResource(resourceName);
try (DataInputStream is = new DataInputStream(resource.openStream())) {
int read = 0;
while (read < classBytes.length) {
final int rc = is.read(classBytes, read, classBytes.length - read);
if (rc == -1) {
break;
}
read += rc;
}
return defineClass(name, classBytes, 0, read);
}
catch (IOException e) {
throw new ClassNotFoundException(name);
}
}
}
}

@ -0,0 +1,64 @@
package com.zaxxer.hikari.pool;
import com.zaxxer.hikari.mocks.StubConnection;
import com.zaxxer.hikari.pool.TestElf.FauxWebClassLoader;
import com.zaxxer.hikari.util.JavassistProxyFactory;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.Statement;
import java.util.stream.Stream;
public class TestJavassistCodegen {
@Test
public void testCodegen() throws Exception {
String tmp = System.getProperty("java.io.tmpdir");
JavassistProxyFactory.main(tmp + (tmp.endsWith("/") ? "" : "/"));
Path base = Paths.get(tmp, "target/classes/com/zaxxer/hikari/pool".split("/"));
Assert.assertTrue("", Files.isRegularFile(base.resolve("HikariProxyConnection.class")));
Assert.assertTrue("", Files.isRegularFile(base.resolve("HikariProxyStatement.class")));
Assert.assertTrue("", Files.isRegularFile(base.resolve("HikariProxyCallableStatement.class")));
Assert.assertTrue("", Files.isRegularFile(base.resolve("HikariProxyPreparedStatement.class")));
Assert.assertTrue("", Files.isRegularFile(base.resolve("HikariProxyResultSet.class")));
Assert.assertTrue("", Files.isRegularFile(base.resolve("ProxyFactory.class")));
FauxWebClassLoader fauxClassLoader = new FauxWebClassLoader();
Class<?> proxyFactoryClass = fauxClassLoader.loadClass("com.zaxxer.hikari.pool.ProxyFactory");
Connection connection = new StubConnection();
Class<?> fastListClass = fauxClassLoader.loadClass("com.zaxxer.hikari.util.FastList");
Object fastList = fastListClass.getConstructor(Class.class).newInstance(Statement.class);
Object proxyConnection = getMethod(proxyFactoryClass, "getProxyConnection")
.invoke(null,
null /*poolEntry*/,
connection,
fastList,
null /*leakTask*/,
0L /*now*/,
Boolean.FALSE /*isReadOnly*/,
Boolean.FALSE /*isAutoCommit*/);
Assert.assertNotNull(proxyConnection);
Object proxyStatement = getMethod(proxyConnection.getClass(), "createStatement", 0)
.invoke(proxyConnection);
Assert.assertNotNull(proxyStatement);
}
private Method getMethod(Class<?> clazz, String methodName, Integer... parameterCount)
{
return Stream.of(clazz.getDeclaredMethods())
.filter(method -> method.getName().equals(methodName))
.filter(method -> (parameterCount.length == 0 || parameterCount[0] == method.getParameterCount()))
.peek(method -> method.setAccessible(true))
.findFirst()
.orElseThrow(RuntimeException::new);
}
}

@ -16,6 +16,8 @@
package com.zaxxer.hikari.util;
import com.zaxxer.hikari.pool.TestElf;
import com.zaxxer.hikari.pool.TestElf.FauxWebClassLoader;
import com.zaxxer.hikari.util.ConcurrentBag.IConcurrentBagEntry;
import org.junit.FixMethodOrder;
import org.junit.Test;
@ -23,12 +25,9 @@ import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
@ -80,37 +79,6 @@ public class TomcatConcurrentBagLeakTest
assertNotNull(ex);
}
static class FauxWebClassLoader extends ClassLoader
{
static final byte[] classBytes = new byte[16_000];
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
if (name.startsWith("java") || name.startsWith("org")) {
return super.loadClass(name, true);
}
final String resourceName = "/" + name.replace('.', '/') + ".class";
final URL resource = this.getClass().getResource(resourceName);
try (DataInputStream is = new DataInputStream(resource.openStream())) {
int read = 0;
while (read < classBytes.length) {
final int rc = is.read(classBytes, read, classBytes.length - read);
if (rc == -1) {
break;
}
read += rc;
}
return defineClass(name, classBytes, 0, read);
}
catch (IOException e) {
throw new ClassNotFoundException(name);
}
}
}
public static class PoolEntry implements IConcurrentBagEntry
{
private int state;
@ -143,7 +111,7 @@ public class TomcatConcurrentBagLeakTest
@SuppressWarnings("WeakerAccess")
public Exception failureException;
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "ResultOfMethodCallIgnored"})
public void createConcurrentBag() throws InterruptedException
{
try (ConcurrentBag<PoolEntry> bag = new ConcurrentBag<>((x) -> CompletableFuture.completedFuture(Boolean.TRUE))) {

Loading…
Cancel
Save