diff --git a/README.md b/README.md
index 92c14efb..31978b6b 100644
--- a/README.md
+++ b/README.md
@@ -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 |
diff --git a/src/main/java/com/zaxxer/hikari/HikariConfig.java b/src/main/java/com/zaxxer/hikari/HikariConfig.java
index 98dbb565..be618cd6 100644
--- a/src/main/java/com/zaxxer/hikari/HikariConfig.java
+++ b/src/main/java/com/zaxxer/hikari/HikariConfig.java
@@ -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()
diff --git a/src/main/java/com/zaxxer/hikari/HikariJNDIFactory.java b/src/main/java/com/zaxxer/hikari/HikariJNDIFactory.java
index a3c09a18..51360289 100644
--- a/src/main/java/com/zaxxer/hikari/HikariJNDIFactory.java
+++ b/src/main/java/com/zaxxer/hikari/HikariJNDIFactory.java
@@ -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 javax.naming.Reference
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) {
diff --git a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
index 54314848..d0906e17 100644
--- a/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
+++ b/src/main/java/com/zaxxer/hikari/pool/HikariPool.java
@@ -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)) {
diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolBase.java b/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
index d0de7ebf..0dab0642 100644
--- a/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
+++ b/src/main/java/com/zaxxer/hikari/pool/PoolBase.java
@@ -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 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());
}
}
}
diff --git a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java
index f85d4693..6cb82e25 100644
--- a/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java
+++ b/src/main/java/com/zaxxer/hikari/pool/PoolEntry.java
@@ -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()
diff --git a/src/main/java/com/zaxxer/hikari/util/DefaultThreadFactory.java b/src/main/java/com/zaxxer/hikari/util/DefaultThreadFactory.java
deleted file mode 100644
index 2db11b3a..00000000
--- a/src/main/java/com/zaxxer/hikari/util/DefaultThreadFactory.java
+++ /dev/null
@@ -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;
- }
-}
diff --git a/src/main/java/com/zaxxer/hikari/util/UtilityElf.java b/src/main/java/com/zaxxer/hikari/util/UtilityElf.java
index b9d8a7b5..6e828eb5 100644
--- a/src/main/java/com/zaxxer/hikari/util/UtilityElf.java
+++ b/src/main/java/com/zaxxer/hikari/util/UtilityElf.java
@@ -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;
+ }
+ }
}
diff --git a/src/test/java/com/zaxxer/hikari/pool/TestJNDI.java b/src/test/java/com/zaxxer/hikari/pool/TestJNDI.java
index 280810bf..404c9312 100644
--- a/src/test/java/com/zaxxer/hikari/pool/TestJNDI.java
+++ b/src/test/java/com/zaxxer/hikari/pool/TestJNDI.java
@@ -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"));
}
}
diff --git a/src/test/java/com/zaxxer/hikari/pool/TestValidation.java b/src/test/java/com/zaxxer/hikari/pool/TestValidation.java
index f5214f8b..2642dd99 100644
--- a/src/test/java/com/zaxxer/hikari/pool/TestValidation.java
+++ b/src/test/java/com/zaxxer/hikari/pool/TestValidation.java
@@ -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