Minor cleanup.

pull/825/head
Brett Wooldridge 8 years ago
parent eafc799f91
commit 0ab35e7445

@ -45,6 +45,7 @@ import com.codahale.metrics.health.HealthCheckRegistry;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.util.PropertyElf;
@SuppressWarnings({"SameParameterValue", "unused"})
public class HikariConfig implements HikariConfigMXBean
{
private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);
@ -55,7 +56,7 @@ public class HikariConfig implements HikariConfigMXBean
private static final long MAX_LIFETIME = MINUTES.toMillis(30);
private static final int DEFAULT_POOL_SIZE = 10;
private static boolean unitTest;
private static boolean unitTest = false;
// Properties changeable at runtime through the MBean
//
@ -176,8 +177,7 @@ public class HikariConfig implements HikariConfigMXBean
/**
* Set the SQL query to be executed to test the validity of connections. Using
* the JDBC4 <code>Connection.isValid()</code> method to test connection validity can
* be more efficient on some databases and is recommended. See
* {@link HikariConfig#setJdbc4ConnectionTest(boolean)}.
* be more efficient on some databases and is recommended.
*
* @param connectionTestQuery a SQL query string
*/
@ -431,7 +431,7 @@ public class HikariConfig implements HikariConfigMXBean
* initial connection validation is performed, this timeout does not override the
* {@code connectionTimeout} or {@code validationTimeout}; they will be honored before this
* timeout is applied. The default value is one millisecond.
*
*
* @param initializationFailTimeout the number of milliseconds before the
* pool initialization fails, or 0 to validate connection setup but continue with
* pool start, or less than zero to skip all initialization checks and start the
@ -466,7 +466,7 @@ public class HikariConfig implements HikariConfigMXBean
public void setInitializationFailFast(boolean failFast)
{
LOGGER.warn("The initializationFailFast propery is deprecated, see initializationFailTimeout");
initializationFailTimeout = (failFast ? 1 : -1);
}
@ -528,15 +528,7 @@ public class HikariConfig implements HikariConfigMXBean
}
if (metricRegistry != null) {
if (metricRegistry instanceof String) {
try {
InitialContext initCtx = new InitialContext();
metricRegistry = initCtx.lookup((String) metricRegistry);
}
catch (NamingException e) {
throw new IllegalArgumentException(e);
}
}
metricRegistry = getObjectOrPerformJndiLookup(metricRegistry);
if (!(metricRegistry instanceof MetricRegistry)) {
throw new IllegalArgumentException("Class must be an instance of com.codahale.metrics.MetricRegistry");
@ -546,6 +538,20 @@ public class HikariConfig implements HikariConfigMXBean
this.metricRegistry = metricRegistry;
}
private Object getObjectOrPerformJndiLookup(Object object)
{
if (object instanceof String) {
try {
InitialContext initCtx = new InitialContext();
return initCtx.lookup((String) object);
}
catch (NamingException e) {
throw new IllegalArgumentException(e);
}
}
return object;
}
/**
* Get the Codahale HealthCheckRegistry, could be null.
*
@ -564,15 +570,7 @@ public class HikariConfig implements HikariConfigMXBean
public void setHealthCheckRegistry(Object healthCheckRegistry)
{
if (healthCheckRegistry != null) {
if (healthCheckRegistry instanceof String) {
try {
InitialContext initCtx = new InitialContext();
healthCheckRegistry = initCtx.lookup((String) healthCheckRegistry);
}
catch (NamingException e) {
throw new IllegalArgumentException(e);
}
}
healthCheckRegistry = getObjectOrPerformJndiLookup(healthCheckRegistry);
if (!(healthCheckRegistry instanceof HealthCheckRegistry)) {
throw new IllegalArgumentException("Class must be an instance of com.codahale.metrics.health.HealthCheckRegistry");
@ -757,7 +755,7 @@ public class HikariConfig implements HikariConfigMXBean
{
this.scheduledExecutor = executor;
}
public String getTransactionIsolation()
{
return transactionIsolationName;
@ -816,6 +814,7 @@ public class HikariConfig implements HikariConfigMXBean
this.threadFactory = threadFactory;
}
@SuppressWarnings("StatementWithEmptyBody")
public void validate()
{
if (poolName == null) {
@ -852,7 +851,8 @@ public class HikariConfig implements HikariConfigMXBean
LOGGER.warn("{} - using dataSourceClassName and ignoring jdbcUrl.", poolName);
}
}
else if (jdbcUrl != null) {
else if (jdbcUrl != null || dataSourceJndiName != null) {
// ok
}
else if (driverClassName != null) {
LOGGER.error("{} - jdbcUrl is required with driverClassName.", poolName);
@ -913,6 +913,7 @@ public class HikariConfig implements HikariConfigMXBean
}
}
@SuppressWarnings("StatementWithEmptyBody")
private void logConfiguration()
{
LOGGER.debug("{} - configuration:", poolName);
@ -947,12 +948,12 @@ public class HikariConfig implements HikariConfigMXBean
LOGGER.debug((prop + "................................................").substring(0, 32) + value);
}
catch (Exception e) {
continue;
// continue
}
}
}
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)) {

@ -107,7 +107,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag
this.connectionBag = new ConcurrentBag<>(this);
this.suspendResumeLock = config.isAllowPoolSuspension() ? new SuspendResumeLock() : SuspendResumeLock.FAUX_LOCK;
initializeHouseKeepingExecutorService();
this.houseKeepingExecutorService = initializeHouseKeepingExecutorService();
checkFailFast();
@ -131,7 +131,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag
this.leakTask = new ProxyLeakTask(config.getLeakDetectionThreshold(), houseKeepingExecutorService);
this.houseKeeperTask = this.houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 100L, HOUSEKEEPING_PERIOD_MS, MILLISECONDS);
this.houseKeeperTask = houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 100L, HOUSEKEEPING_PERIOD_MS, MILLISECONDS);
}
/**
@ -423,6 +423,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag
}
}
@SuppressWarnings("unused")
int[] getPoolStateCounts()
{
return connectionBag.getStateCounts();
@ -552,17 +553,17 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag
return false;
}
private void initializeHouseKeepingExecutorService()
private ScheduledExecutorService initializeHouseKeepingExecutorService()
{
if (config.getScheduledExecutor() == null) {
final ThreadFactory threadFactory = Optional.ofNullable(config.getThreadFactory()).orElse(new DefaultThreadFactory(poolName + " housekeeper", true));
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, threadFactory, new ThreadPoolExecutor.DiscardPolicy());
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
executor.setRemoveOnCancelPolicy(true);
this.houseKeepingExecutorService = executor;
return executor;
}
else {
this.houseKeepingExecutorService = config.getScheduledExecutor();
return config.getScheduledExecutor();
}
}
@ -697,7 +698,7 @@ public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBag
.sorted(LASTACCESS_REVERSE_COMPARABLE)
.skip(config.getMinimumIdle())
.filter(p -> elapsedMillis(p.lastAccessed, now) > idleTimeout)
.filter(p -> connectionBag.reserve(p))
.filter(connectionBag::reserve)
.forEachOrdered(p -> closeConnection(p, "(connection has passed idleTimeout)"));
}

@ -33,8 +33,11 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -61,9 +64,9 @@ abstract class PoolBase
protected final HikariConfig config;
protected final String poolName;
protected long connectionTimeout;
protected long validationTimeout;
protected IMetricsTrackerDelegate metricsTracker;
long connectionTimeout;
long validationTimeout;
IMetricsTrackerDelegate metricsTracker;
private static final String[] RESET_STATES = {"readOnly", "autoCommit", "isolation", "catalog", "netTimeout"};
private static final int UNINITIALIZED = -1;
@ -244,7 +247,7 @@ abstract class PoolBase
/**
* Register MBeans for HikariConfig and HikariPool.
*
* @param pool a HikariPool instance
* @param hikariPool a HikariPool instance
*/
void registerMBeans(final HikariPool hikariPool)
{
@ -300,8 +303,6 @@ abstract class PoolBase
/**
* Create/initialize the underlying DataSource.
*
* @return a DataSource instance
*/
private void initializeDataSource()
{
@ -310,6 +311,7 @@ abstract class PoolBase
final String password = config.getPassword();
final String dsClassName = config.getDataSourceClassName();
final String driverClassName = config.getDriverClassName();
final String dataSourceJNDI = config.getDataSourceJNDI();
final Properties dataSourceProperties = config.getDataSourceProperties();
DataSource dataSource = config.getDataSource();
@ -320,6 +322,14 @@ abstract class PoolBase
else if (jdbcUrl != null && dataSource == null) {
dataSource = new DriverDataSource(jdbcUrl, driverClassName, dataSourceProperties, username, password);
}
else if (dataSourceJNDI != null && dataSource == null) {
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup(dataSourceJNDI);
} catch (NamingException e) {
throw new PoolInitializationException(e);
}
}
if (dataSource != null) {
setLoginTimeout(dataSource);
@ -334,7 +344,7 @@ abstract class PoolBase
*
* @return a Connection connection
*/
Connection newConnection() throws Exception
private Connection newConnection() throws Exception
{
final long start = currentTime();
@ -375,7 +385,7 @@ abstract class PoolBase
* Setup a connection initial state.
*
* @param connection a Connection
* @throws SQLException thrown from driver
* @throws ConnectionSetupException thrown if any exception is encountered
*/
private void setupConnection(final Connection connection) throws ConnectionSetupException
{
@ -610,7 +620,7 @@ abstract class PoolBase
{
private static final long serialVersionUID = 929872118275916521L;
public ConnectionSetupException(Throwable t)
ConnectionSetupException(Throwable t)
{
super(t);
}
@ -635,7 +645,7 @@ abstract class PoolBase
}
}
static interface IMetricsTrackerDelegate extends AutoCloseable
interface IMetricsTrackerDelegate extends AutoCloseable
{
default void recordConnectionUsage(PoolEntry poolEntry) {}

@ -47,7 +47,9 @@ final class PoolEntry implements IConcurrentBagEntry
Connection connection;
long lastAccessed;
long lastBorrowed;
private volatile int state;
@SuppressWarnings("FieldCanBeLocal")
private volatile int state = 0;
private volatile boolean evict;
private volatile ScheduledFuture<?> endOfLife;
@ -60,12 +62,7 @@ final class PoolEntry implements IConcurrentBagEntry
static
{
LASTACCESS_REVERSE_COMPARABLE = new Comparator<PoolEntry>() {
@Override
public int compare(final PoolEntry entryOne, final PoolEntry entryTwo) {
return Long.compare(entryTwo.lastAccessed, entryOne.lastAccessed);
}
};
LASTACCESS_REVERSE_COMPARABLE = (entryOne, entryTwo) -> Long.compare(entryTwo.lastAccessed, entryOne.lastAccessed);
stateUpdater = AtomicIntegerFieldUpdater.newUpdater(PoolEntry.class, "state");
}
@ -94,7 +91,9 @@ final class PoolEntry implements IConcurrentBagEntry
}
/**
* @param endOfLife
* Set the end of life {@link ScheduledFuture}.
*
* @param endOfLife this PoolEntry/Connection's end of life {@link ScheduledFuture}
*/
void setFutureEol(final ScheduledFuture<?> endOfLife)
{

@ -19,7 +19,6 @@ package com.zaxxer.hikari.pool;
import static com.zaxxer.hikari.util.ClockSource.currentTime;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.CallableStatement;
import java.sql.Connection;
@ -54,6 +53,7 @@ public abstract class ProxyConnection implements Connection
private static final Set<String> ERROR_STATES;
private static final Set<Integer> ERROR_CODES;
@SuppressWarnings("WeakerAccess")
protected Connection delegate;
private final PoolEntry poolEntry;
@ -101,10 +101,7 @@ public abstract class ProxyConnection implements Connection
@Override
public final String toString()
{
return new StringBuilder(64)
.append(this.getClass().getSimpleName()).append('@').append(System.identityHashCode(this))
.append(" wrapping ")
.append(delegate).toString();
return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegate;
}
// ***********************************************************************
@ -186,23 +183,27 @@ public abstract class ProxyConnection implements Connection
leakTask.cancel();
}
private final synchronized <T extends Statement> T trackStatement(final T statement)
private synchronized <T extends Statement> T trackStatement(final T statement)
{
openStatements.add(statement);
return statement;
}
private final void closeStatements()
private void closeStatements()
{
final int size = openStatements.size();
if (size > 0) {
for (int i = 0; i < size && delegate != ClosedConnection.CLOSED_CONNECTION; i++) {
try (Statement statement = openStatements.get(i)) {
// automatic resource cleanup
statement.close();
}
catch (SQLException e) {
checkException(e);
LOGGER.warn("{} - Connection {} marked as broken because of an exception closing open statements during Connection.close()",
poolEntry.getPoolName(), delegate);
leakTask.cancel();
poolEntry.evict("(exception closing Statements during Connection.close())");
delegate = ClosedConnection.CLOSED_CONNECTION;
}
}
@ -449,24 +450,19 @@ public abstract class ProxyConnection implements Connection
private static Connection getClosedConnection()
{
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
final String methodName = method.getName();
if ("abort".equals(methodName)) {
return Void.TYPE;
}
else if ("isValid".equals(methodName)) {
return Boolean.FALSE;
}
else if ("toString".equals(methodName)) {
return ClosedConnection.class.getCanonicalName();
}
throw new SQLException("Connection is closed");
InvocationHandler handler = (proxy, method, args) -> {
final String methodName = method.getName();
if ("abort".equals(methodName)) {
return Void.TYPE;
}
else if ("isValid".equals(methodName)) {
return Boolean.FALSE;
}
else if ("toString".equals(methodName)) {
return ClosedConnection.class.getCanonicalName();
}
throw new SQLException("Connection is closed");
};
return (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[] { Connection.class }, handler);

@ -30,6 +30,7 @@ import com.zaxxer.hikari.util.FastList;
*
* @author Brett Wooldridge
*/
@SuppressWarnings("unused")
public final class ProxyFactory
{
private ProxyFactory()
@ -39,13 +40,13 @@ public final class ProxyFactory
/**
* Create a proxy for the specified {@link Connection} instance.
* @param poolEntry
* @param connection
* @param openStatements
* @param leakTask
* @param now
* @param isReadOnly
* @param isAutoCommit
* @param poolEntry the PoolEntry holding pool state
* @param connection the raw database Connection
* @param openStatements a reusable list to track open Statement instances
* @param leakTask the ProxyLeakTask for this connection
* @param now the current timestamp
* @param isReadOnly the default readOnly state of the connection
* @param isAutoCommit the default autoCommit state of the connection
* @return a proxy that wraps the specified {@link Connection}
*/
static ProxyConnection getProxyConnection(final PoolEntry poolEntry, final Connection connection, final FastList<Statement> openStatements, final ProxyLeakTask leakTask, final long now, final boolean isReadOnly, final boolean isAutoCommit)

@ -27,7 +27,7 @@ import java.sql.SQLException;
*/
public abstract class ProxyPreparedStatement extends ProxyStatement implements PreparedStatement
{
protected ProxyPreparedStatement(ProxyConnection connection, PreparedStatement statement)
ProxyPreparedStatement(ProxyConnection connection, PreparedStatement statement)
{
super(connection, statement);
}
@ -50,7 +50,7 @@ public abstract class ProxyPreparedStatement extends ProxyStatement implements P
{
connection.markCommitStateDirty();
ResultSet resultSet = ((PreparedStatement) delegate).executeQuery();
return ProxyFactory.getProxyResultSet(connection, this, resultSet);
return ProxyFactory.getProxyResultSet(connection, this, resultSet);
}
/** {@inheritDoc} */

@ -19,7 +19,6 @@ package com.zaxxer.hikari.pool;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Wrapper;
/**
* This is the proxy class for java.sql.ResultSet.
@ -30,7 +29,7 @@ public abstract class ProxyResultSet implements ResultSet
{
protected final ProxyConnection connection;
protected final ProxyStatement statement;
protected final ResultSet delegate;
final ResultSet delegate;
protected ProxyResultSet(ProxyConnection connection, ProxyStatement statement, ResultSet resultSet)
{
@ -39,6 +38,7 @@ public abstract class ProxyResultSet implements ResultSet
this.delegate = resultSet;
}
@SuppressWarnings("unused")
final SQLException checkException(SQLException e)
{
return connection.checkException(e);
@ -48,10 +48,7 @@ public abstract class ProxyResultSet implements ResultSet
@Override
public String toString()
{
return new StringBuilder(64)
.append(this.getClass().getSimpleName()).append('@').append(System.identityHashCode(this))
.append(" wrapping ")
.append(delegate).toString();
return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegate;
}
// **********************************************************************
@ -97,7 +94,7 @@ public abstract class ProxyResultSet implements ResultSet
if (iface.isInstance(delegate)) {
return (T) delegate;
}
else if (delegate instanceof Wrapper) {
else if (delegate != null) {
return delegate.unwrap(iface);
}

@ -20,7 +20,6 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Wrapper;
/**
* This is the proxy class for java.sql.Statement.
@ -30,17 +29,18 @@ import java.sql.Wrapper;
public abstract class ProxyStatement implements Statement
{
protected final ProxyConnection connection;
protected final Statement delegate;
final Statement delegate;
private boolean isClosed;
private ResultSet proxyResultSet;
protected ProxyStatement(ProxyConnection connection, Statement statement)
ProxyStatement(ProxyConnection connection, Statement statement)
{
this.connection = connection;
this.delegate = statement;
}
@SuppressWarnings("unused")
final SQLException checkException(SQLException e)
{
return connection.checkException(e);
@ -51,10 +51,7 @@ public abstract class ProxyStatement implements Statement
public final String toString()
{
final String delegateToString = delegate.toString();
return new StringBuilder(64 + delegateToString.length())
.append(this.getClass().getSimpleName()).append('@').append(System.identityHashCode(this))
.append(" wrapping ")
.append(delegateToString).toString();
return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegateToString;
}
// **********************************************************************
@ -231,7 +228,7 @@ public abstract class ProxyStatement implements Statement
if (iface.isInstance(delegate)) {
return (T) delegate;
}
else if (delegate instanceof Wrapper) {
else if (delegate != null) {
return delegate.unwrap(iface);
}

@ -45,7 +45,7 @@ import java.util.Calendar;
*/
public class StubPreparedStatement extends StubStatement implements PreparedStatement
{
public StubPreparedStatement(Connection connection)
StubPreparedStatement(Connection connection)
{
super(connection);
}

@ -19,7 +19,6 @@ package com.zaxxer.hikari.pool;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.HashMap;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
@ -56,20 +55,7 @@ public final class TestElf
}
}
@SuppressWarnings("unchecked")
public static HashMap<Object, HikariPool> getMultiPool(HikariDataSource ds)
{
try {
Field field = ds.getClass().getDeclaredField("multiPool");
field.setAccessible(true);
return (HashMap<Object, HikariPool>) field.get(ds);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static boolean getConnectionCommitDirtyState(Connection connection)
static boolean getConnectionCommitDirtyState(Connection connection)
{
try {
Field field = ProxyConnection.class.getDeclaredField("isCommitStateDirty");
@ -81,7 +67,7 @@ public final class TestElf
}
}
public static void setConfigUnitTest(boolean unitTest)
static void setConfigUnitTest(boolean unitTest)
{
try {
Field field = HikariConfig.class.getDeclaredField("unitTest");
@ -93,7 +79,7 @@ public final class TestElf
}
}
public static void setSlf4jTargetStream(Class<?> clazz, PrintStream stream)
static void setSlf4jTargetStream(Class<?> clazz, PrintStream stream)
{
try {
Log4jLogger log4Jlogger = (Log4jLogger) LoggerFactory.getLogger(clazz);
@ -114,7 +100,7 @@ public final class TestElf
}
}
public static void setSlf4jLogLevel(Class<?> clazz, Level logLevel)
static void setSlf4jLogLevel(Class<?> clazz, Level logLevel)
{
try {
Log4jLogger log4Jlogger = (Log4jLogger) LoggerFactory.getLogger(clazz);
@ -144,7 +130,7 @@ public final class TestElf
return config;
}
public static HikariDataSource newHikariDataSource()
static HikariDataSource newHikariDataSource()
{
final StackTraceElement callerStackTrace = Thread.currentThread().getStackTrace()[2];

@ -15,17 +15,21 @@
*/
package com.zaxxer.hikari.pool;
import static com.zaxxer.hikari.pool.TestElf.newHikariConfig;
import static com.zaxxer.hikari.pool.TestElf.newHikariDataSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import com.zaxxer.hikari.HikariConfig;
import org.junit.Test;
import org.osjava.sj.jndi.AbstractContext;
@ -33,6 +37,8 @@ import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariJNDIFactory;
import com.zaxxer.hikari.mocks.StubDataSource;
import java.sql.Connection;
public class TestJNDI
{
@Test
@ -94,6 +100,27 @@ public class TestJNDI
}
}
@Test
public void testJndiLookup4() throws Exception
{
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.memory.MemoryContextFactory");
System.setProperty("org.osjava.sj.jndi.shared", "true");
InitialContext ic = new InitialContext();
StubDataSource ds = new StubDataSource();
Context subcontext = ic.createSubcontext("java:/comp/env/jdbc");
subcontext.bind("java:/comp/env/jdbc/myDS", ds);
HikariConfig config = newHikariConfig();
config.setDataSourceJNDI("java:/comp/env/jdbc/myDS");
try (HikariDataSource hds = new HikariDataSource(config);
Connection conn = hds.getConnection()) {
assertNotNull(conn);
}
}
private class BogusContext extends AbstractContext
{
@Override

Loading…
Cancel
Save