Fixes seal the HikariDataSource after the pool is started. Improve constructor documentation.

pull/1058/head
Brett Wooldridge
parent a5bdec0ad7
commit c48ccf6e12

@ -98,6 +98,8 @@ public class HikariConfig implements HikariConfigMXBean
private Object healthCheckRegistry; private Object healthCheckRegistry;
private Properties healthCheckProperties; private Properties healthCheckProperties;
private volatile boolean sealed;
/** /**
* Default constructor * Default constructor
*/ */
@ -161,6 +163,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setConnectionTimeout(long connectionTimeoutMs) public void setConnectionTimeout(long connectionTimeoutMs)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (connectionTimeoutMs == 0) { if (connectionTimeoutMs == 0) {
this.connectionTimeout = Integer.MAX_VALUE; this.connectionTimeout = Integer.MAX_VALUE;
} }
@ -183,6 +187,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setIdleTimeout(long idleTimeoutMs) public void setIdleTimeout(long idleTimeoutMs)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (idleTimeoutMs < 0) { if (idleTimeoutMs < 0) {
throw new IllegalArgumentException("idleTimeout cannot be negative"); throw new IllegalArgumentException("idleTimeout cannot be negative");
} }
@ -200,6 +206,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setLeakDetectionThreshold(long leakDetectionThresholdMs) public void setLeakDetectionThreshold(long leakDetectionThresholdMs)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.leakDetectionThreshold = leakDetectionThresholdMs; this.leakDetectionThreshold = leakDetectionThresholdMs;
} }
@ -214,6 +222,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setMaxLifetime(long maxLifetimeMs) public void setMaxLifetime(long maxLifetimeMs)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.maxLifetime = maxLifetimeMs; this.maxLifetime = maxLifetimeMs;
} }
@ -228,6 +238,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setMaximumPoolSize(int maxPoolSize) public void setMaximumPoolSize(int maxPoolSize)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (maxPoolSize < 1) { if (maxPoolSize < 1) {
throw new IllegalArgumentException("maxPoolSize cannot be less than 1"); throw new IllegalArgumentException("maxPoolSize cannot be less than 1");
} }
@ -245,6 +257,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setMinimumIdle(int minIdle) public void setMinimumIdle(int minIdle)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (minIdle < 0) { if (minIdle < 0) {
throw new IllegalArgumentException("minimumIdle cannot be negative"); throw new IllegalArgumentException("minimumIdle cannot be negative");
} }
@ -267,6 +281,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setPassword(String password) public void setPassword(String password)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.password = password; this.password = password;
} }
@ -288,6 +304,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setUsername(String username) public void setUsername(String username)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.username = username; this.username = username;
} }
@ -302,6 +320,8 @@ public class HikariConfig implements HikariConfigMXBean
@Override @Override
public void setValidationTimeout(long validationTimeoutMs) public void setValidationTimeout(long validationTimeoutMs)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (validationTimeoutMs < 250) { if (validationTimeoutMs < 250) {
throw new IllegalArgumentException("validationTimeout cannot be less than 250ms"); throw new IllegalArgumentException("validationTimeout cannot be less than 250ms");
} }
@ -330,6 +350,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setCatalog(String catalog) public void setCatalog(String catalog)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.catalog = catalog; this.catalog = catalog;
} }
@ -352,6 +374,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setConnectionTestQuery(String connectionTestQuery) public void setConnectionTestQuery(String connectionTestQuery)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.connectionTestQuery = connectionTestQuery; this.connectionTestQuery = connectionTestQuery;
} }
@ -375,6 +399,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setConnectionInitSql(String connectionInitSql) public void setConnectionInitSql(String connectionInitSql)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.connectionInitSql = connectionInitSql; this.connectionInitSql = connectionInitSql;
} }
@ -397,6 +423,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setDataSource(DataSource dataSource) public void setDataSource(DataSource dataSource)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.dataSource = dataSource; this.dataSource = dataSource;
} }
@ -417,6 +445,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setDataSourceClassName(String className) public void setDataSourceClassName(String className)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.dataSourceClassName = className; this.dataSourceClassName = className;
} }
@ -435,6 +465,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void addDataSourceProperty(String propertyName, Object value) public void addDataSourceProperty(String propertyName, Object value)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
dataSourceProperties.put(propertyName, value); dataSourceProperties.put(propertyName, value);
} }
@ -445,6 +477,8 @@ public class HikariConfig implements HikariConfigMXBean
public void setDataSourceJNDI(String jndiDataSource) public void setDataSourceJNDI(String jndiDataSource)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.dataSourceJndiName = jndiDataSource; this.dataSourceJndiName = jndiDataSource;
} }
@ -455,6 +489,8 @@ public class HikariConfig implements HikariConfigMXBean
public void setDataSourceProperties(Properties dsProperties) public void setDataSourceProperties(Properties dsProperties)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
dataSourceProperties.putAll(dsProperties); dataSourceProperties.putAll(dsProperties);
} }
@ -465,6 +501,8 @@ public class HikariConfig implements HikariConfigMXBean
public void setDriverClassName(String driverClassName) public void setDriverClassName(String driverClassName)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
Class<?> driverClass = null; Class<?> driverClass = null;
ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader();
try { try {
@ -507,6 +545,8 @@ public class HikariConfig implements HikariConfigMXBean
public void setJdbcUrl(String jdbcUrl) public void setJdbcUrl(String jdbcUrl)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.jdbcUrl = jdbcUrl; this.jdbcUrl = jdbcUrl;
} }
@ -527,6 +567,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setAutoCommit(boolean isAutoCommit) public void setAutoCommit(boolean isAutoCommit)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.isAutoCommit = isAutoCommit; this.isAutoCommit = isAutoCommit;
} }
@ -549,6 +591,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setAllowPoolSuspension(boolean isAllowPoolSuspension) public void setAllowPoolSuspension(boolean isAllowPoolSuspension)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.isAllowPoolSuspension = isAllowPoolSuspension; this.isAllowPoolSuspension = isAllowPoolSuspension;
} }
@ -599,6 +643,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setInitializationFailTimeout(long initializationFailTimeout) public void setInitializationFailTimeout(long initializationFailTimeout)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.initializationFailTimeout = initializationFailTimeout; this.initializationFailTimeout = initializationFailTimeout;
} }
@ -625,6 +671,8 @@ public class HikariConfig implements HikariConfigMXBean
@Deprecated @Deprecated
public void setInitializationFailFast(boolean failFast) public void setInitializationFailFast(boolean failFast)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
LOGGER.warn("The initializationFailFast propery is deprecated, see initializationFailTimeout"); LOGGER.warn("The initializationFailFast propery is deprecated, see initializationFailTimeout");
initializationFailTimeout = (failFast ? 1 : -1); initializationFailTimeout = (failFast ? 1 : -1);
@ -649,6 +697,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setIsolateInternalQueries(boolean isolate) public void setIsolateInternalQueries(boolean isolate)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.isIsolateInternalQueries = isolate; this.isIsolateInternalQueries = isolate;
} }
@ -661,6 +711,8 @@ public class HikariConfig implements HikariConfigMXBean
@Deprecated @Deprecated
public void setJdbc4ConnectionTest(boolean useIsValid) public void setJdbc4ConnectionTest(boolean useIsValid)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
LOGGER.warn("The jdbcConnectionTest property is now deprecated, see the documentation for connectionTestQuery"); LOGGER.warn("The jdbcConnectionTest property is now deprecated, see the documentation for connectionTestQuery");
} }
@ -671,6 +723,8 @@ public class HikariConfig implements HikariConfigMXBean
public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory) public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (metricRegistry != null) { if (metricRegistry != null) {
throw new IllegalStateException("cannot use setMetricsTrackerFactory() and setMetricRegistry() together"); throw new IllegalStateException("cannot use setMetricsTrackerFactory() and setMetricRegistry() together");
} }
@ -695,6 +749,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setMetricRegistry(Object metricRegistry) public void setMetricRegistry(Object metricRegistry)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (metricsTrackerFactory != null) { if (metricsTrackerFactory != null) {
throw new IllegalStateException("cannot use setMetricRegistry() and setMetricsTrackerFactory() together"); throw new IllegalStateException("cannot use setMetricRegistry() and setMetricsTrackerFactory() together");
} }
@ -730,6 +786,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setHealthCheckRegistry(Object healthCheckRegistry) public void setHealthCheckRegistry(Object healthCheckRegistry)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
if (healthCheckRegistry != null) { if (healthCheckRegistry != null) {
healthCheckRegistry = getObjectOrPerformJndiLookup(healthCheckRegistry); healthCheckRegistry = getObjectOrPerformJndiLookup(healthCheckRegistry);
@ -748,11 +806,15 @@ public class HikariConfig implements HikariConfigMXBean
public void setHealthCheckProperties(Properties healthCheckProperties) public void setHealthCheckProperties(Properties healthCheckProperties)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.healthCheckProperties.putAll(healthCheckProperties); this.healthCheckProperties.putAll(healthCheckProperties);
} }
public void addHealthCheckProperty(String key, String value) public void addHealthCheckProperty(String key, String value)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
healthCheckProperties.setProperty(key, value); healthCheckProperties.setProperty(key, value);
} }
@ -773,6 +835,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setReadOnly(boolean readOnly) public void setReadOnly(boolean readOnly)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.isReadOnly = readOnly; this.isReadOnly = readOnly;
} }
@ -794,6 +858,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setRegisterMbeans(boolean register) public void setRegisterMbeans(boolean register)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.isRegisterMbeans = register; this.isRegisterMbeans = register;
} }
@ -812,6 +878,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setPoolName(String poolName) public void setPoolName(String poolName)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.poolName = poolName; this.poolName = poolName;
} }
@ -834,6 +902,8 @@ public class HikariConfig implements HikariConfigMXBean
@Deprecated @Deprecated
public void setScheduledExecutorService(ScheduledThreadPoolExecutor executor) public void setScheduledExecutorService(ScheduledThreadPoolExecutor executor)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.scheduledExecutor = executor; this.scheduledExecutor = executor;
} }
@ -854,6 +924,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setScheduledExecutor(ScheduledExecutorService executor) public void setScheduledExecutor(ScheduledExecutorService executor)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.scheduledExecutor = executor; this.scheduledExecutor = executor;
} }
@ -874,7 +946,10 @@ public class HikariConfig implements HikariConfigMXBean
/** /**
* Set the default schema name to be set on connections. * Set the default schema name to be set on connections.
*/ */
public void setSchema(String schema) { public void setSchema(String schema)
{
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.schema = schema; this.schema = schema;
} }
@ -887,6 +962,8 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setTransactionIsolation(String isolationLevel) public void setTransactionIsolation(String isolationLevel)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.transactionIsolationName = isolationLevel; this.transactionIsolationName = isolationLevel;
} }
@ -907,9 +984,16 @@ public class HikariConfig implements HikariConfigMXBean
*/ */
public void setThreadFactory(ThreadFactory threadFactory) public void setThreadFactory(ThreadFactory threadFactory)
{ {
if (sealed) throw new IllegalStateException("The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.");
this.threadFactory = threadFactory; this.threadFactory = threadFactory;
} }
protected void seal()
{
this.sealed = true;
}
/** /**
* Deprecated, use {@link #copyStateTo(HikariConfig)}. * Deprecated, use {@link #copyStateTo(HikariConfig)}.
* <p> * <p>

@ -47,10 +47,14 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
private volatile HikariPool pool; private volatile HikariPool pool;
/** /**
* Default constructor. Setters be used to configure the pool. Using * Default constructor. Setters are be used to configure the pool. Using
* this constructor vs. {@link #HikariDataSource(HikariConfig)} will * this constructor vs. {@link #HikariDataSource(HikariConfig)} will
* result in {@link #getConnection()} performance that is slightly lower * result in {@link #getConnection()} performance that is slightly lower
* due to lazy initialization checks. * due to lazy initialization checks.
*
* The first call to {@link #getConnection()} starts the pool. Once the pool
* is started, the configuration is "sealed" and no further configuration
* changes are possible -- except via {@link HikariConfigMXBean}.
*/ */
public HikariDataSource() public HikariDataSource()
{ {
@ -59,7 +63,12 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
} }
/** /**
* Construct a HikariDataSource with the specified configuration. * Construct a HikariDataSource with the specified configuration. The
* {@link HikariConfig} is copied and the pool is started by invoking this
* constructor.
*
* The {@link HikariConfig} can be modified without affecting the HikariDataSource
* and used to initialize another HikariDataSource instance.
* *
* @param configuration a HikariConfig instance * @param configuration a HikariConfig instance
*/ */
@ -67,6 +76,7 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
{ {
configuration.validate(); configuration.validate();
configuration.copyStateTo(this); configuration.copyStateTo(this);
this.seal();
LOGGER.info("{} - Starting...", configuration.getPoolName()); LOGGER.info("{} - Starting...", configuration.getPoolName());
pool = fastPathPool = new HikariPool(this); pool = fastPathPool = new HikariPool(this);
@ -95,6 +105,7 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
LOGGER.info("{} - Starting...", getPoolName()); LOGGER.info("{} - Starting...", getPoolName());
try { try {
pool = result = new HikariPool(this); pool = result = new HikariPool(this);
this.seal();
} }
catch (PoolInitializationException pie) { catch (PoolInitializationException pie) {
if (pie.getCause() instanceof SQLException) { if (pie.getCause() instanceof SQLException) {
@ -277,7 +288,7 @@ public class HikariDataSource extends HikariConfig implements DataSource, Closea
/** /**
* Get the {@code HikariConfigMXBean} for this HikariDataSource instance. * Get the {@code HikariConfigMXBean} for this HikariDataSource instance.
* *
* @return the {@code HikariConfigMXBean} instance. * @return the {@code HikariConfigMXBean} instance.
*/ */
public HikariConfigMXBean getHikariConfigMXBean() public HikariConfigMXBean getHikariConfigMXBean()

Loading…
Cancel
Save