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