pull/566/head
Brett Wooldridge 9 years ago
commit 68a52f1431

@ -378,11 +378,11 @@ Here is a list of JDBC *DataSource* classes for popular databases:
| Firebird | Jaybird | org.firebirdsql.pool.FBSimpleDataSource |
| H2 | H2 | org.h2.jdbcx.JdbcDataSource |
| HSQLDB | HSQLDB | org.hsqldb.jdbc.JDBCDataSource |
| IBM AS400 | IBM | com.ibm.as400.access.AS400JDBCDriver |
| IBM DB2 | DB2 | com.ibm.db2.jcc.DB2SimpleDataSource |
| MariaDB & MySQL | MariaDB | org.mariadb.jdbc.MySQLDataSource |
| MySQL | Connector/J | com.mysql.jdbc.jdbc2.optional.MysqlDataSource |
| IBM DB2 | IBM JCC | com.ibm.db2.jcc.DB2SimpleDataSource |
| IBM Informix | IBM Informix | com.informix.jdbcx.IfxDataSource |
| MS SQL Server | Microsoft | com.microsoft.sqlserver.jdbc.SQLServerDataSource |
| MySQL | Connector/J | com.mysql.jdbc.jdbc2.optional.MysqlDataSource |
| MySQL/MariaDB | MariaDB | org.mariadb.jdbc.MySQLDataSource |
| Oracle | Oracle | oracle.jdbc.pool.OracleDataSource |
| OrientDB | OrientDB | com.orientechnologies.orient.jdbc.OrientDataSource |
| PostgreSQL | pgjdbc-ng | com.impossibl.postgres.jdbc.PGDataSource |

@ -116,14 +116,15 @@ public class HikariConfig implements HikariConfigMXBean
dataSourceProperties = new Properties();
healthCheckProperties = new Properties();
minIdle = -1;
maxPoolSize = -1;
maxLifetime = MAX_LIFETIME;
connectionTimeout = CONNECTION_TIMEOUT;
validationTimeout = VALIDATION_TIMEOUT;
idleTimeout = IDLE_TIMEOUT;
isAutoCommit = true;
isInitializationFailFast = true;
minIdle = -1;
maxPoolSize = 10;
maxLifetime = MAX_LIFETIME;
String systemProp = System.getProperty("hikaricp.configurationFile");
if ( systemProp != null) {
@ -775,8 +776,7 @@ public class HikariConfig implements HikariConfigMXBean
if (poolName == null) {
poolName = "HikariPool-" + POOL_NUMBER.getAndIncrement();
}
if (poolName.contains(":") && isRegisterMbeans) {
else if (isRegisterMbeans && poolName.contains(":")) {
throw new IllegalArgumentException("poolName cannot contain ':' when used with JMX");
}
@ -828,8 +828,7 @@ public class HikariConfig implements HikariConfigMXBean
}
if (idleTimeout + TimeUnit.SECONDS.toMillis(1) > maxLifetime && maxLifetime > 0) {
LOGGER.warn("idleTimeout is close to or greater than maxLifetime, disabling it.");
maxLifetime = idleTimeout;
LOGGER.warn("idleTimeout is close to or more than maxLifetime, disabling it.");
idleTimeout = 0;
}
@ -838,29 +837,33 @@ public class HikariConfig implements HikariConfigMXBean
idleTimeout = IDLE_TIMEOUT;
}
if (leakDetectionThreshold != 0 && leakDetectionThreshold < TimeUnit.SECONDS.toMillis(2) && !unitTest) {
LOGGER.warn("leakDetectionThreshold is less than 2000ms, setting to minimum 2000ms.");
leakDetectionThreshold = 2000L;
if (leakDetectionThreshold > 0 && !unitTest) {
if (leakDetectionThreshold < TimeUnit.SECONDS.toMillis(2) || (leakDetectionThreshold > maxLifetime && maxLifetime > 0)) {
LOGGER.warn("leakDetectionThreshold is less than 2000ms or more than maxLifetime, disabling it.");
leakDetectionThreshold = 0L;
}
}
if (connectionTimeout != Integer.MAX_VALUE) {
if (validationTimeout > connectionTimeout) {
LOGGER.warn("validationTimeout should be less than connectionTimeout, setting validationTimeout to connectionTimeout");
LOGGER.warn("validationTimeout should be less than connectionTimeout, setting validationTimeout to connectionTimeout.");
validationTimeout = connectionTimeout;
}
if (maxLifetime > 0 && connectionTimeout > maxLifetime) {
LOGGER.warn("connectionTimeout should be less than maxLifetime, setting maxLifetime to connectionTimeout");
maxLifetime = connectionTimeout;
LOGGER.warn("connectionTimeout should be less than maxLifetime, setting connectionTimeout to maxLifetime.");
connectionTimeout = maxLifetime;
}
}
if (minIdle < 0) {
minIdle = maxPoolSize;
}
else if (minIdle > maxPoolSize) {
LOGGER.warn("minIdle should be less than maxPoolSize, setting maxPoolSize to minIdle");
if (maxPoolSize < 0) {
if (minIdle < 0) {
minIdle = 10;
}
maxPoolSize = minIdle;
}
else if (minIdle < 0 || minIdle > maxPoolSize) {
minIdle = maxPoolSize;
}
}
private void logConfiguration()

@ -40,7 +40,7 @@ import com.zaxxer.hikari.util.PropertyElf;
public class HikariJNDIFactory implements ObjectFactory
{
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception
synchronized public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception
{
// We only know how to deal with <code>javax.naming.Reference</code> that specify a class name of "javax.sql.DataSource"
if (!(obj instanceof Reference)) {
@ -67,27 +67,27 @@ public class HikariJNDIFactory implements ObjectFactory
return createDataSource(properties, nameCtx);
}
private DataSource createDataSource(Properties properties, Context context) throws NamingException
private DataSource createDataSource(final Properties properties, final Context context) throws NamingException
{
if (properties.getProperty("dataSourceJNDI") != null) {
return lookupJndiDataSource(properties, context);
String jndiName = properties.getProperty("dataSourceJNDI");
if (jndiName != null) {
return lookupJndiDataSource(properties, context, jndiName);
}
return new HikariDataSource(new HikariConfig(properties));
}
private DataSource lookupJndiDataSource(Properties properties, Context context) throws NamingException
private DataSource lookupJndiDataSource(final Properties properties, final Context context, final String jndiName) throws NamingException
{
if (context == null) {
throw new RuntimeException("dataSourceJNDI property is configured, but local JNDI context is null.");
throw new RuntimeException("JNDI context does not found for dataSourceJNDI : " + jndiName);
}
String jndiName = properties.getProperty("dataSourceJNDI");
DataSource jndiDS = (DataSource) context.lookup(jndiName);
if (jndiDS == null) {
context = new InitialContext();
jndiDS = (DataSource) context.lookup(jndiName);
context.close();
final Context ic = new InitialContext();
jndiDS = (DataSource) ic.lookup(jndiName);
ic.close();
}
if (jndiDS != null) {

@ -45,7 +45,7 @@ import com.zaxxer.hikari.metrics.dropwizard.CodahaleMetricsTrackerFactory;
import com.zaxxer.hikari.util.ClockSource;
import com.zaxxer.hikari.util.ConcurrentBag;
import com.zaxxer.hikari.util.ConcurrentBag.IBagStateListener;
import com.zaxxer.hikari.util.DefaultThreadFactory;
import com.zaxxer.hikari.util.UtilityElf.DefaultThreadFactory;
import com.zaxxer.hikari.util.SuspendResumeLock;
import static com.zaxxer.hikari.pool.PoolEntry.LASTACCESS_COMPARABLE;
@ -67,17 +67,16 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
private static final ClockSource clockSource = ClockSource.INSTANCE;
private final long ALIVE_BYPASS_WINDOW_MS = Long.getLong("com.zaxxer.hikari.aliveBypassWindowMs", TimeUnit.MILLISECONDS.toMillis(500));
private final long HOUSEKEEPING_PERIOD_MS = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", TimeUnit.SECONDS.toMillis(30));
private final PoolEntryCreator POOL_ENTRY_CREATOR = new PoolEntryCreator();
private static final int POOL_NORMAL = 0;
private static final int POOL_SUSPENDED = 1;
private static final int POOL_SHUTDOWN = 2;
private volatile int poolState;
private final long ALIVE_BYPASS_WINDOW_MS = Long.getLong("com.zaxxer.hikari.aliveBypassWindowMs", TimeUnit.MILLISECONDS.toMillis(500));
private final long HOUSEKEEPING_PERIOD_MS = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", TimeUnit.SECONDS.toMillis(30));
private final PoolEntryCreator POOL_ENTRY_CREATOR = new PoolEntryCreator();
private final AtomicInteger totalConnections;
private final ThreadPoolExecutor addConnectionExecutor;
private final ThreadPoolExecutor closeConnectionExecutor;
@ -89,7 +88,6 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
private final SuspendResumeLock suspendResumeLock;
private MetricsTrackerDelegate metricsTracker;
private boolean isRecordMetrics;
/**
* Construct a HikariPool with the specified configuration.
@ -104,9 +102,6 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
this.totalConnections = new AtomicInteger();
this.suspendResumeLock = config.isAllowPoolSuspension() ? new SuspendResumeLock() : SuspendResumeLock.FAUX_LOCK;
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), "Hikari connection adder (pool " + poolName + ")", config.getThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
this.closeConnectionExecutor = createThreadPoolExecutor(1 + (config.getMaximumPoolSize() / 2), "Hikari connection closer (pool " + poolName + ")", config.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
if (config.getMetricsTrackerFactory() != null) {
setMetricsTrackerFactory(config.getMetricsTrackerFactory());
}
@ -120,8 +115,12 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
checkFailFast();
ThreadFactory threadFactory = config.getThreadFactory();
this.addConnectionExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), "Hikari connection adder (pool " + poolName + ")", threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.closeConnectionExecutor = createThreadPoolExecutor(1 + (config.getMaximumPoolSize() / 2), "Hikari connection closer (pool " + poolName + ")", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
if (config.getScheduledExecutorService() == null) {
ThreadFactory threadFactory = config.getThreadFactory() != null ? config.getThreadFactory() : new DefaultThreadFactory("Hikari housekeeper (pool " + poolName + ")", true);
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("Hikari housekeeper (pool " + poolName + ")", true);
this.houseKeepingExecutorService = new ScheduledThreadPoolExecutor(1, threadFactory, new ThreadPoolExecutor.DiscardPolicy());
this.houseKeepingExecutorService.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.houseKeepingExecutorService.setRemoveOnCancelPolicy(true);
@ -265,8 +264,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
public void setMetricRegistry(Object metricRegistry)
{
this.isRecordMetrics = metricRegistry != null;
if (isRecordMetrics) {
if (metricRegistry != null) {
setMetricsTrackerFactory(new CodahaleMetricsTrackerFactory((MetricRegistry) metricRegistry));
}
else {
@ -276,8 +274,7 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory)
{
this.isRecordMetrics = metricsTrackerFactory != null;
if (isRecordMetrics) {
if (metricsTrackerFactory != null) {
this.metricsTracker = new MetricsTrackerDelegate(metricsTrackerFactory.create(config.getPoolName(), getPoolStats()));
}
else {
@ -407,13 +404,11 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
final void closeConnection(final PoolEntry poolEntry, final String closureReason)
{
if (connectionBag.remove(poolEntry)) {
final Connection connection = poolEntry.connection;
poolEntry.close();
final int tc = totalConnections.decrementAndGet();
if (tc < 0) {
LOGGER.warn("{} - Internal accounting inconsistency, totalConnections={}", poolName, tc, new Exception());
LOGGER.warn("{} - Unexpected value of totalConnections={}", poolName, tc, new Exception());
}
final Connection connection = poolEntry.close();
closeConnectionExecutor.execute(new Runnable() {
@Override
public void run() {
@ -588,8 +583,8 @@ public class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateL
validationTimeout = config.getValidationTimeout();
leakTask.updateLeakDetectionThreshold(config.getLeakDetectionThreshold());
final long now = clockSource.currentTime();
final long idleTimeout = config.getIdleTimeout();
final long now = clockSource.currentTime();
// Detect retrograde time, allowing +128ms as per NTP spec.
if (clockSource.plusMillis(now, 128) < clockSource.plusMillis(previous, HOUSEKEEPING_PERIOD_MS)) {

@ -29,10 +29,10 @@ import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.metrics.MetricsTracker;
import com.zaxxer.hikari.util.ClockSource;
import com.zaxxer.hikari.util.DefaultThreadFactory;
import com.zaxxer.hikari.util.DriverDataSource;
import com.zaxxer.hikari.util.PropertyElf;
import com.zaxxer.hikari.util.UtilityElf;
import com.zaxxer.hikari.util.UtilityElf.DefaultThreadFactory;
abstract class PoolBase
{
@ -48,15 +48,17 @@ abstract class PoolBase
private static final int FALSE = 0;
private int networkTimeout;
private int transactionIsolation;
private int isNetworkTimeoutSupported;
private int isQueryTimeoutSupported;
private int defaultTransactionIsolation;
private int transactionIsolation;
private Executor netTimeoutExecutor;
private DataSource dataSource;
private final String catalog;
private final boolean isReadOnly;
private final boolean isAutoCommit;
private final boolean isUseJdbc4Validation;
private final boolean isIsolateInternalQueries;
private final AtomicReference<Throwable> lastConnectionFailure;
@ -144,7 +146,7 @@ abstract class PoolBase
}
catch (SQLException e) {
lastConnectionFailure.set(e);
LOGGER.warn("{} - Connection {} failed alive test with exception {}", poolName, connection, e.getMessage());
LOGGER.warn("{} - Failed to validate connection {} ({})", poolName, connection, e.getMessage());
return false;
}
}
@ -330,16 +332,12 @@ abstract class PoolBase
{
networkTimeout = getAndSetNetworkTimeout(connection, connectionTimeout);
checkValidationMode(connection);
checkDriverSupport(connection);
connection.setAutoCommit(isAutoCommit);
connection.setReadOnly(isReadOnly);
connection.setAutoCommit(isAutoCommit);
final int defaultLevel = connection.getTransactionIsolation();
transactionIsolation = (transactionIsolation < 0 || defaultLevel == Connection.TRANSACTION_NONE)
? defaultLevel
: transactionIsolation;
if (transactionIsolation != defaultLevel) {
if (transactionIsolation != defaultTransactionIsolation) {
connection.setTransactionIsolation(transactionIsolation);
}
@ -357,7 +355,7 @@ abstract class PoolBase
*
* @param connection a Connection to check
*/
private void checkValidationMode(final Connection connection) throws SQLException
private void checkDriverSupport(final Connection connection) throws SQLException
{
if (!isValidChecked) {
if (isUseJdbc4Validation) {
@ -365,7 +363,7 @@ abstract class PoolBase
connection.isValid(1);
}
catch (Throwable e) {
LOGGER.debug("{} - Connection.isValid() is not supported, configure connection test query. ({})", poolName, e.getMessage());
LOGGER.warn("{} - Failed to execute isValid() for connection, configure connection test query. ({})", poolName, e.getMessage());
throw e;
}
}
@ -374,10 +372,14 @@ abstract class PoolBase
executeSql(connection, config.getConnectionTestQuery(), false, isIsolateInternalQueries && !isAutoCommit);
}
catch (Throwable e) {
LOGGER.debug("{} - Failed to execute connection test query. ({})", poolName, e.getMessage());
LOGGER.warn("{} - Failed to execute connection test query. ({})", poolName, e.getMessage());
throw e;
}
}
defaultTransactionIsolation = connection.getTransactionIsolation();
if (transactionIsolation == -1) {
transactionIsolation = defaultTransactionIsolation;
}
isValidChecked = true;
}
}
@ -398,7 +400,7 @@ abstract class PoolBase
catch (Throwable e) {
if (isQueryTimeoutSupported == UNINITIALIZED) {
isQueryTimeoutSupported = FALSE;
LOGGER.debug("{} - Statement.setQueryTimeout() is not supported ({})", poolName, e.getMessage());
LOGGER.warn("{} - Unable to set query timeout for statement. ({})", poolName, e.getMessage());
}
}
}
@ -424,7 +426,7 @@ abstract class PoolBase
catch (Throwable e) {
if (isNetworkTimeoutSupported == UNINITIALIZED) {
isNetworkTimeoutSupported = FALSE;
LOGGER.debug("{} - Connection.setNetworkTimeout() is not supported ({})", poolName, e.getMessage());
LOGGER.warn("{} - Unable to get/set network timeout for connection. ({})", poolName, e.getMessage());
}
}
}
@ -459,17 +461,15 @@ abstract class PoolBase
{
if (sql != null) {
try (Statement statement = connection.createStatement()) {
//con created few ms before, set query timeout is omitted
statement.execute(sql);
if (!isReadOnly) {
if (isCommit) {
connection.commit();
}
else if (isRollback) {
connection.rollback();
}
}
if (!isReadOnly) {
if (isCommit) {
connection.commit();
}
else if (isRollback) {
connection.rollback();
}
}
}
@ -484,7 +484,8 @@ abstract class PoolBase
netTimeoutExecutor = new SynchronousExecutor();
}
else {
ThreadFactory threadFactory = config.getThreadFactory() != null ? config.getThreadFactory() : new DefaultThreadFactory("Hikari JDBC-timeout executor", true);
ThreadFactory threadFactory = config.getThreadFactory();
threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("Hikari JDBC-timeout executor", true);
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(threadFactory);
executor.allowCoreThreadTimeOut(true);
executor.setKeepAliveTime(15, TimeUnit.SECONDS);
@ -502,7 +503,7 @@ abstract class PoolBase
command.run();
}
catch (Throwable t) {
LoggerFactory.getLogger(PoolBase.class).debug("Exception executing {}", command, t);
LoggerFactory.getLogger(PoolBase.class).debug("Failed to execute: {}", command, t);
}
}
}
@ -520,7 +521,7 @@ abstract class PoolBase
dataSource.setLoginTimeout((int) TimeUnit.MILLISECONDS.toSeconds(Math.max(1000L, connectionTimeout)));
}
catch (Throwable e) {
LOGGER.warn("{} - Unable to set DataSource login timeout", poolName, e);
LOGGER.warn("{} - Unable to set login timeout for data source. ({})", poolName, e.getMessage());
}
}
}

@ -166,14 +166,16 @@ final class PoolEntry implements IConcurrentBagEntry
state.lazySet(update);
}
void close()
Connection close()
{
if (endOfLife != null && !endOfLife.isDone() && !endOfLife.cancel(false)) {
LOGGER.warn("{} - maxLifeTime expiration task cancellation unexpectedly returned false for connection {}", getPoolName(), connection);
}
endOfLife = null;
Connection con = connection;
connection = null;
endOfLife = null;
return con;
}
private String stateToString()

@ -1,36 +0,0 @@
/*
* 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.util;
import java.util.concurrent.ThreadFactory;
public class DefaultThreadFactory implements ThreadFactory {
private final String threadName;
private final boolean daemon;
public DefaultThreadFactory(String threadName, boolean daemon) {
this.threadName = threadName;
this.daemon = daemon;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, threadName);
thread.setDaemon(daemon);
return thread;
}
}

@ -73,18 +73,16 @@ public final class UtilityElf
try {
Class<?> loaded = UtilityElf.class.getClassLoader().loadClass(className);
if (args.length == 0) {
return clazz.cast(loaded.newInstance());
}
Class<?>[] argClasses = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
argClasses[i] = args[i].getClass();
}
if (args.length > 0) {
Constructor<?> constructor = loaded.getConstructor(argClasses);
return clazz.cast(constructor.newInstance(args));
}
return clazz.cast(loaded.newInstance());
Constructor<?> constructor = loaded.getConstructor(argClasses);
return clazz.cast(constructor.newInstance(args));
}
catch (Exception e) {
throw new RuntimeException(e);
@ -150,4 +148,22 @@ public final class UtilityElf
return -1;
}
public static final class DefaultThreadFactory implements ThreadFactory {
private final String threadName;
private final boolean daemon;
public DefaultThreadFactory(String threadName, boolean daemon) {
this.threadName = threadName;
this.daemon = daemon;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, threadName);
thread.setDaemon(daemon);
return thread;
}
}
}

@ -46,9 +46,10 @@ public class TestJNDI
ref.add(new BogusRef("dataSource.loginTimeout", "10"));
Context nameCtx = new BogusContext();
HikariDataSource ds = (HikariDataSource) jndi.getObjectInstance(ref, null, nameCtx, null);
Assert.assertNotNull(ds);
Assert.assertEquals("foo", ds.getUsername());
try (HikariDataSource ds = (HikariDataSource) jndi.getObjectInstance(ref, null, nameCtx, null)) {
Assert.assertNotNull(ds);
Assert.assertEquals("foo", ds.getUsername());
}
}
@Test
@ -67,9 +68,10 @@ public class TestJNDI
ref.add(new BogusRef("dataSource.loginTimeout", "10"));
Context nameCtx = new BogusContext2();
HikariDataSource ds = (HikariDataSource) jndi.getObjectInstance(ref, null, nameCtx, null);
Assert.assertNotNull(ds);
Assert.assertEquals("foo", ds.getUsername());
try (HikariDataSource ds = (HikariDataSource) jndi.getObjectInstance(ref, null, nameCtx, null)) {
Assert.assertNotNull(ds);
Assert.assertEquals("foo", ds.getUsername());
}
}
@Test
@ -84,7 +86,7 @@ public class TestJNDI
Assert.fail();
}
catch (RuntimeException e) {
Assert.assertTrue(e.getMessage().contains("JNDI context is null"));
Assert.assertTrue(e.getMessage().contains("JNDI context does not found"));
}
}

@ -159,7 +159,7 @@ public class TestValidation
config.validate();
String s = new String(baos.toByteArray());
Assert.assertTrue("Expected exception to contain 'greater than maxLifetime' but contains *" + s + "*", s.contains("greater than maxLifetime"));
Assert.assertTrue("idleTimeout is close to or more than maxLifetime, disabling it." + s + "*", s.contains("is close to or more than maxLifetime"));
}
@Test
@ -208,16 +208,11 @@ public class TestValidation
@Test
public void validateInvalidLeakDetection()
{
try {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setLeakDetectionThreshold(1000L);
config.validate();
Assert.assertEquals(2000L, config.getLeakDetectionThreshold());
}
catch (IllegalArgumentException ise) {
// pass
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setLeakDetectionThreshold(1000L);
config.validate();
Assert.assertEquals(0L, config.getLeakDetectionThreshold());
}
@Test

Loading…
Cancel
Save