Java 7'ification and code consolidation.

pull/295/head
Brett Wooldridge 10 years ago
parent c95bc7383b
commit 5f6fbbdd37

@ -16,6 +16,10 @@
package com.zaxxer.hikari;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Connection;
@ -31,10 +35,11 @@ import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.proxy.JavassistProxyFactory;
import com.zaxxer.hikari.util.PropertyBeanSetter;
import com.zaxxer.hikari.util.UtilityElf;
public abstract class AbstractHikariConfig implements HikariConfigMBean
public class HikariConfig implements HikariConfigMBean
{
private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);
@ -84,10 +89,15 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
private Object healthCheckRegistry;
private Properties healthCheckProperties;
static
{
JavassistProxyFactory.initialize();
}
/**
* Default constructor
*/
public AbstractHikariConfig()
public HikariConfig()
{
dataSourceProperties = new Properties();
healthCheckProperties = new Properties();
@ -118,7 +128,7 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
*
* @param properties the name of the property file
*/
public AbstractHikariConfig(Properties properties)
public HikariConfig(Properties properties)
{
this();
PropertyBeanSetter.setTargetFromProperties(this, properties);
@ -131,7 +141,7 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
*
* @param propertyFileName the name of the property file
*/
public AbstractHikariConfig(String propertyFileName)
public HikariConfig(String propertyFileName)
{
this();
@ -821,11 +831,27 @@ public abstract class AbstractHikariConfig implements HikariConfigMBean
}
}
abstract protected void loadProperties(String propertyFileName);
private void loadProperties(String propertyFileName)
{
final File propFile = new File(propertyFileName);
try (final InputStream is = propFile.isFile() ? new FileInputStream(propFile) : this.getClass().getResourceAsStream(propertyFileName)) {
if (is != null) {
Properties props = new Properties();
props.load(is);
PropertyBeanSetter.setTargetFromProperties(this, props);
}
else {
throw new IllegalArgumentException("Property file " + propertyFileName + " was not found.");
}
}
catch (IOException io) {
throw new RuntimeException("Error loading properties file", io);
}
}
public void copyState(AbstractHikariConfig other)
public void copyState(HikariConfig other)
{
for (Field field : AbstractHikariConfig.class.getDeclaredFields()) {
for (Field field : HikariConfig.class.getDeclaredFields()) {
if (!Modifier.isFinal(field.getModifiers())) {
field.setAccessible(true);
try {

@ -25,11 +25,11 @@ import static com.zaxxer.hikari.util.UtilityElf.createInstance;
import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.UtilityElf.elapsedTimeMs;
import static com.zaxxer.hikari.util.UtilityElf.getTransactionIsolation;
import static com.zaxxer.hikari.util.UtilityElf.setRemoveOnCancelPolicy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLTimeoutException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
@ -160,13 +160,13 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
this.houseKeepingExecutorService = new ScheduledThreadPoolExecutor(1, threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.houseKeepingExecutorService.scheduleAtFixedRate(getHouseKeeper(), delayPeriod, delayPeriod, TimeUnit.MILLISECONDS);
this.houseKeepingExecutorService.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.houseKeepingExecutorService.setRemoveOnCancelPolicy(true);
this.leakTask = (configuration.getLeakDetectionThreshold() == 0) ? LeakTask.NO_LEAK : new LeakTask(configuration.getLeakDetectionThreshold(), houseKeepingExecutorService);
if (configuration.getHealthCheckRegistry() != null) {
CodahaleHealthChecker.registerHealthChecks(this, (HealthCheckRegistry) configuration.getHealthCheckRegistry());
}
setRemoveOnCancelPolicy(houseKeepingExecutorService);
poolUtils.setLoginTimeout(dataSource, connectionTimeout);
registerMBeans(configuration, this);
initializeConnections();
@ -453,13 +453,6 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
*/
protected abstract void closeConnection(final PoolBagEntry bagEntry);
/**
* Check whether the connection is alive or not.
*
* @param connection the connection to test
* @return true if the connection is alive, false if it is not alive or we timed out
*/
protected abstract boolean isConnectionAlive(final Connection connection);
/**
* Attempt to abort() active connections on Java7+, or close() them on Java6.
@ -517,6 +510,43 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
fillPool();
}
/**
* Check whether the connection is alive or not.
*
* @param connection the connection to test
* @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out
*/
private boolean isConnectionAlive(final Connection connection)
{
try {
int timeoutSec = (int) TimeUnit.MILLISECONDS.toSeconds(validationTimeout);
if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec);
}
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, validationTimeout);
try (Statement statement = connection.createStatement()) {
poolUtils.setQueryTimeout(statement, timeoutSec);
statement.executeQuery(configuration.getConnectionTestQuery());
}
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
poolUtils.setNetworkTimeout(connection, originalTimeout);
return true;
}
catch (SQLException e) {
LOGGER.warn("Exception during keep alive check, that means the connection ({}) must be dead.", connection, e);
return false;
}
}
/**
* Construct the user's connection customizer, if specified.
*

@ -0,0 +1,265 @@
/*
* Copyright (C) 2013, 2014 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.proxy;
import java.lang.reflect.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.LoaderClassPath;
import javassist.Modifier;
import javassist.NotFoundException;
import com.zaxxer.hikari.util.ClassLoaderUtils;
/**
* This class generates the proxy objects for {@link Connection}, {@link Statement},
* {@link PreparedStatement}, and {@link CallableStatement}. Additionally it injects
* method bodies into the {@link ProxyFactory} class methods that can instantiate
* instances of the generated proxies.
*
* @author Brett Wooldridge
*/
public final class JavassistProxyFactory
{
private ClassPool classPool;
static {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(JavassistProxyFactory.class.getClassLoader());
JavassistProxyFactory proxyFactoryFactory = new JavassistProxyFactory();
proxyFactoryFactory.modifyProxyFactory();
}
catch (Exception e) {
throw new RuntimeException("Fatal exception during proxy generation", e);
}
finally {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
/**
* Simply invoking this method causes the initialization of this class. All work
* by this class is performed in static initialization.
*/
public static void initialize()
{
// no-op
}
private JavassistProxyFactory() throws Exception
{
classPool = new ClassPool();
classPool.importPackage("java.sql");
classPool.appendClassPath(new LoaderClassPath(this.getClass().getClassLoader()));
// Cast is not needed for these
String methodBody = "{ try { return delegate.method($$); } catch (SQLException e) { throw checkException(e); } }";
generateProxyClass(Connection.class, ConnectionProxy.class, methodBody);
generateProxyClass(Statement.class, StatementProxy.class, methodBody);
generateProxyClass(ResultSet.class, ResultSetProxy.class, methodBody);
// For these we have to cast the delegate
methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { throw checkException(e); } }";
generateProxyClass(PreparedStatement.class, PreparedStatementProxy.class, methodBody);
generateProxyClass(CallableStatement.class, CallableStatementProxy.class, methodBody);
}
private void modifyProxyFactory() throws Exception
{
String packageName = JavassistProxyFactory.class.getPackage().getName();
CtClass proxyCt = classPool.getCtClass("com.zaxxer.hikari.proxy.ProxyFactory");
for (CtMethod method : proxyCt.getMethods()) {
switch (method.getName()) {
case "getProxyConnection":
method.setBody("{return new " + packageName + ".ConnectionJavassistProxy($$);}");
break;
case "getProxyStatement":
method.setBody("{return new " + packageName + ".StatementJavassistProxy($$);}");
break;
case "getProxyPreparedStatement":
method.setBody("{return new " + packageName + ".PreparedStatementJavassistProxy($$);}");
break;
case "getProxyCallableStatement":
method.setBody("{return new " + packageName + ".CallableStatementJavassistProxy($$);}");
break;
case "getProxyResultSet":
method.setBody("{return new " + packageName + ".ResultSetJavassistProxy($$);}");
break;
}
}
proxyCt.toClass(classPool.getClassLoader(), getClass().getProtectionDomain());
}
/**
* Generate Javassist Proxy Classes
*/
@SuppressWarnings("unchecked")
private <T> Class<T> generateProxyClass(Class<T> primaryInterface, Class<?> superClass, String methodBody) throws Exception
{
// Make a new class that extends one of the JavaProxy classes (ie. superClass); use the name to XxxJavassistProxy instead of XxxProxy
String superClassName = superClass.getName();
CtClass superClassCt = classPool.getCtClass(superClassName);
CtClass targetCt = classPool.makeClass(superClassName.replace("Proxy", "JavassistProxy"), superClassCt);
targetCt.setModifiers(Modifier.FINAL);
// Make a set of method signatures we inherit implementation for, so we don't generate delegates for these
Set<String> superSigs = new HashSet<String>();
for (CtMethod method : superClassCt.getMethods()) {
if ((method.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
superSigs.add(method.getName() + method.getSignature());
}
}
Set<String> methods = new HashSet<String>();
Set<Class<?>> interfaces = ClassLoaderUtils.getAllInterfaces(primaryInterface);
for (Class<?> intf : interfaces) {
CtClass intfCt = classPool.getCtClass(intf.getName());
targetCt.addInterface(intfCt);
for (CtMethod intfMethod : intfCt.getDeclaredMethods()) {
final String signature = intfMethod.getName() + intfMethod.getSignature();
// don't generate delegates for methods we override
if (superSigs.contains(signature)) {
continue;
}
// Ignore already added methods that come from other interfaces
if (methods.contains(signature)) {
continue;
}
// Ignore default methods (only for Jre8 or later)
if (isDefaultMethod(intf, intfCt, intfMethod)) {
continue;
}
// Track what methods we've added
methods.add(signature);
// Clone the method we want to inject into
CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null);
String modifiedBody = methodBody;
// If the super-Proxy has concrete methods (non-abstract), transform the call into a simple super.method() call
CtMethod superMethod = superClassCt.getMethod(intfMethod.getName(), intfMethod.getSignature());
if ((superMethod.getModifiers() & Modifier.ABSTRACT) != Modifier.ABSTRACT) {
modifiedBody = modifiedBody.replace("((cast) ", "");
modifiedBody = modifiedBody.replace("delegate", "super");
modifiedBody = modifiedBody.replace("super)", "super");
}
modifiedBody = modifiedBody.replace("cast", primaryInterface.getName());
// Generate a method that simply invokes the same method on the delegate
if (isThrowsSqlException(intfMethod)) {
modifiedBody = modifiedBody.replace("method", method.getName());
}
else {
modifiedBody = "{ return ((cast) delegate).method($$); }".replace("method", method.getName()).replace("cast", primaryInterface.getName());
}
if (method.getReturnType() == CtClass.voidType) {
modifiedBody = modifiedBody.replace("return", "");
}
method.setBody(modifiedBody);
targetCt.addMethod(method);
}
}
return targetCt.toClass(classPool.getClassLoader(), getClass().getProtectionDomain());
}
private boolean isThrowsSqlException(CtMethod method)
{
try {
for (CtClass clazz : method.getExceptionTypes()) {
if (clazz.getSimpleName().equals("SQLException")) {
return true;
}
}
}
catch (NotFoundException e) {
// fall thru
}
return false;
}
private boolean isDefaultMethod(Class<?> intf, CtClass intfCt, CtMethod intfMethod) throws Exception
{
List<Class<?>> paramTypes = new ArrayList<Class<?>>();
for (CtClass pt : intfMethod.getParameterTypes()) {
paramTypes.add(toJavaClass(pt));
}
return intf.getDeclaredMethod(intfMethod.getName(), paramTypes.toArray(new Class[0])).toString().contains("default ");
}
private Class<?> toJavaClass(CtClass cls) throws Exception
{
if (cls.getName().endsWith("[]")) {
return Array.newInstance(toJavaClass(cls.getName().replace("[]", "")), 0).getClass();
}
else {
return toJavaClass(cls.getName());
}
}
private Class<?> toJavaClass(String cn) throws Exception
{
switch (cn) {
case "int":
return int.class;
case "long":
return long.class;
case "short":
return short.class;
case "byte":
return byte.class;
case "float":
return float.class;
case "double":
return double.class;
case "boolean":
return boolean.class;
case "char":
return char.class;
case "void":
return void.class;
default:
return Class.forName(cn);
}
}
}

@ -71,17 +71,12 @@ public class ConcurrentBag<T extends IConcurrentBagEntry>
public ConcurrentBag(IBagStateListener listener)
{
this.sharedList = new CopyOnWriteArrayList<T>();
this.synchronizer = createQueuedSynchronizer();
this.synchronizer = new Synchronizer();
this.sequence = new AtomicLong(1);
this.listener = listener;
this.threadList = new ThreadLocal<ArrayList<WeakReference<IConcurrentBagEntry>>>();
}
protected AbstractQueuedLongSynchronizer createQueuedSynchronizer()
{
throw new RuntimeException("createQueuedSynchronizer() method must be overridden");
}
/**
* The method will borrow a BagEntry from the bag, blocking for the
* specified timeout if none are available.
@ -307,4 +302,28 @@ public class ConcurrentBag<T extends IConcurrentBagEntry>
LOGGER.info(bagEntry.toString());
}
}
/**
* Our private synchronizer that handles notify/wait type semantics.
*/
private static final class Synchronizer extends AbstractQueuedLongSynchronizer
{
private static final long serialVersionUID = 104753538004341218L;
@Override
protected long tryAcquireShared(long seq)
{
return getState() > seq && !hasQueuedPredecessors() ? 1L : -1L;
}
/** {@inheritDoc} */
@Override
protected boolean tryReleaseShared(long updateSeq)
{
setState(updateSeq);
return true;
}
}
}

@ -21,11 +21,9 @@ import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
/**
*
@ -33,19 +31,6 @@ import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
*/
public final class UtilityElf
{
public static final boolean IS_JAVA7;
static {
boolean b = false;
try {
b = AbstractQueuedLongSynchronizer.class.getMethod("hasQueuedPredecessors", new Class<?>[0]) != null;
}
catch (Exception e) {
}
IS_JAVA7 = b;
}
/**
* Get the elapsed time in millisecond between the specified start time and now.
*
@ -72,18 +57,6 @@ public final class UtilityElf
}
}
/**
* If the scheduled executor supports it, set the removeonCancelPolicy.
*
* @param executor the executor to set
*/
public static void setRemoveOnCancelPolicy(ScheduledThreadPoolExecutor executor)
{
if (IS_JAVA7) {
executor.setRemoveOnCancelPolicy(true);
}
}
/**
* Create and instance of the specified class using the constructor matching the specified
* arguments.

@ -78,7 +78,7 @@ public final class TestElf
public static void setConfigUnitTest(boolean unitTest)
{
try {
Field field = AbstractHikariConfig.class.getDeclaredField("unitTest");
Field field = HikariConfig.class.getDeclaredField("unitTest");
field.setAccessible(true);
field.setBoolean(null, unitTest);
}

@ -84,6 +84,7 @@ public class TestJNDI
}
}
@SuppressWarnings("unchecked")
private class BogusContext extends AbstractContext
{
@Override

@ -20,16 +20,12 @@ import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.util.ConcurrentBag;
import com.zaxxer.hikari.util.IBagStateListener;
import com.zaxxer.hikari.util.Java6ConcurrentBag;
import com.zaxxer.hikari.util.Java7ConcurrentBag;
/**
* This is the primary connection pool class that provides the basic
@ -131,48 +127,6 @@ public final class HikariPool extends BaseHikariPool
}
}
/**
* Check whether the connection is alive or not.
*
* @param connection the connection to test
* @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out
*/
@Override
protected boolean isConnectionAlive(final Connection connection)
{
try {
final int timeoutSec = (int) TimeUnit.MILLISECONDS.toSeconds(validationTimeout);
if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec);
}
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, validationTimeout);
Statement statement = connection.createStatement();
try {
poolUtils.setQueryTimeout(statement, timeoutSec);
statement.executeQuery(configuration.getConnectionTestQuery());
}
finally {
statement.close();
}
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
poolUtils.setNetworkTimeout(connection, originalTimeout);
return true;
}
catch (SQLException e) {
LOGGER.warn("Exception during keep alive check, that means the connection ({}) must be dead.", connection, e);
return false;
}
}
/**
* Attempt to abort() active connections on Java7+, or close() them on Java6.
*
@ -211,7 +165,7 @@ public final class HikariPool extends BaseHikariPool
@Override
protected ConcurrentBag<PoolBagEntry> createConcurrentBag(IBagStateListener listener)
{
return new Java6ConcurrentBag(listener);
return new Java7ConcurrentBag(listener);
}
// ***********************************************************************

@ -17,11 +17,9 @@ package com.zaxxer.hikari.util;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import static com.zaxxer.hikari.util.UtilityElf.IS_JAVA7;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import com.zaxxer.hikari.pool.PoolBagEntry;
@ -45,19 +43,13 @@ import com.zaxxer.hikari.pool.PoolBagEntry;
*
* @param <T> the templated type to store in the bag
*/
public final class Java6ConcurrentBag extends ConcurrentBag<PoolBagEntry>
public final class Java7ConcurrentBag extends ConcurrentBag<PoolBagEntry>
{
public Java6ConcurrentBag(IBagStateListener listener)
public Java7ConcurrentBag(IBagStateListener listener)
{
super(listener);
}
@Override
protected AbstractQueuedLongSynchronizer createQueuedSynchronizer()
{
return new Synchronizer();
}
/**
* This method provides a "snaphot" in time of the BagEntry
* items in the bag in the specified state. It does not "lock"
@ -96,37 +88,4 @@ public final class Java6ConcurrentBag extends ConcurrentBag<PoolBagEntry>
}
return count;
}
/**
* Our private synchronizer that handles notify/wait type semantics.
*/
private static final class Synchronizer extends AbstractQueuedLongSynchronizer
{
private static final long serialVersionUID = 104753538004341218L;
@Override
protected long tryAcquireShared(long seq)
{
return getState() > seq && !java67hasQueuedPredecessors() ? 1L : -1L;
}
/** {@inheritDoc} */
@Override
protected boolean tryReleaseShared(long updateSeq)
{
setState(updateSeq);
return true;
}
private boolean java67hasQueuedPredecessors()
{
if (IS_JAVA7) {
return hasQueuedPredecessors();
}
return false;
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Brett Wooldridge
* Copyright (C) 2015 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -74,7 +74,7 @@ public class OSGiBundleTest
{
if(bundle != null)
{
if(bundle.getSymbolicName().equals("com.zaxxer.HikariCP-java6"))
if(bundle.getSymbolicName().equals("com.zaxxer.HikariCP-java7"))
{
bundleFound = true;
if(bundle.getState() == Bundle.ACTIVE)

@ -20,11 +20,8 @@ import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.util.ConcurrentBag;
@ -114,44 +111,6 @@ public final class HikariPool extends BaseHikariPool
}
}
/**
* Check whether the connection is alive or not.
*
* @param connection the connection to test
* @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out
*/
@Override
protected boolean isConnectionAlive(final Connection connection)
{
try {
int timeoutSec = (int) TimeUnit.MILLISECONDS.toSeconds(validationTimeout);
if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec);
}
final int originalTimeout = poolUtils.getAndSetNetworkTimeout(connection, validationTimeout);
try (Statement statement = connection.createStatement()) {
poolUtils.setQueryTimeout(statement, timeoutSec);
statement.executeQuery(configuration.getConnectionTestQuery());
}
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
poolUtils.setNetworkTimeout(connection, originalTimeout);
return true;
}
catch (SQLException e) {
LOGGER.warn("Exception during keep alive check, that means the connection ({}) must be dead.", connection, e);
return false;
}
}
/**
* Attempt to abort() active connections on Java7+, or close() them on Java6.
*

@ -20,7 +20,6 @@ import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import java.util.stream.Collectors;
import com.zaxxer.hikari.pool.PoolBagEntry;
@ -57,12 +56,6 @@ public final class Java8ConcurrentBag extends ConcurrentBag<PoolBagEntry>
super(listener);
}
@Override
protected AbstractQueuedLongSynchronizer createQueuedSynchronizer()
{
return new Synchronizer();
}
/**
* This method provides a "snaphot" in time of the BagEntry
* items in the bag in the specified state. It does not "lock"
@ -93,27 +86,4 @@ public final class Java8ConcurrentBag extends ConcurrentBag<PoolBagEntry>
{
return (int) sharedList.stream().filter(reference -> reference.state.get() == state).count();
}
/**
* Our private synchronizer that handles notify/wait type semantics.
*/
private static final class Synchronizer extends AbstractQueuedLongSynchronizer
{
private static final long serialVersionUID = 104753538004341218L;
@Override
protected long tryAcquireShared(long seq)
{
return getState() > seq && !hasQueuedPredecessors() ? 1L : -1L;
}
/** {@inheritDoc} */
@Override
protected boolean tryReleaseShared(long updateSeq)
{
setState(updateSeq);
return true;
}
}
}

@ -16,12 +16,9 @@
package com.zaxxer.hikari;
import static com.zaxxer.hikari.util.UtilityElf.IS_JAVA7;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import org.junit.AfterClass;
import org.junit.Assert;
@ -31,7 +28,6 @@ import org.junit.Test;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.pool.PoolBagEntry;
import com.zaxxer.hikari.util.ConcurrentBag;
import com.zaxxer.hikari.util.IConcurrentBagEntry;
import com.zaxxer.hikari.util.Java8ConcurrentBag;
/**
@ -110,60 +106,4 @@ public class TestConcurrentBag
Assert.assertNotNull(notinuse.toString());
}
@Test
public void testConcurrentBag2() throws InterruptedException
{
ConcurrentBag<PoolBagEntry> bag = new FauxJava6ConcurrentBag();
Assert.assertEquals(0, bag.values(IConcurrentBagEntry.STATE_IN_USE).size());
Assert.assertEquals(0, bag.getCount(IConcurrentBagEntry.STATE_IN_USE));
}
private static class FauxJava6ConcurrentBag extends ConcurrentBag<PoolBagEntry>
{
/**
* @param listener
*/
public FauxJava6ConcurrentBag() {
super(null);
}
@Override
protected AbstractQueuedLongSynchronizer createQueuedSynchronizer()
{
return new Synchronizer();
}
}
/**
* Our private synchronizer that handles notify/wait type semantics.
*/
private static final class Synchronizer extends AbstractQueuedLongSynchronizer
{
private static final long serialVersionUID = 104753538004341218L;
@Override
protected long tryAcquireShared(long seq)
{
return getState() > seq && !java67hasQueuedPredecessors() ? 1L : -1L;
}
/** {@inheritDoc} */
@Override
protected boolean tryReleaseShared(long updateSeq)
{
setState(updateSeq);
return true;
}
private boolean java67hasQueuedPredecessors()
{
if (IS_JAVA7) {
return hasQueuedPredecessors();
}
return false;
}
}
}

Loading…
Cancel
Save