001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.dbcp2; 018 019import java.io.OutputStreamWriter; 020import java.io.PrintWriter; 021import java.nio.charset.StandardCharsets; 022import java.security.AccessController; 023import java.security.PrivilegedActionException; 024import java.security.PrivilegedExceptionAction; 025import java.sql.Connection; 026import java.sql.Driver; 027import java.sql.DriverManager; 028import java.sql.SQLException; 029import java.sql.SQLFeatureNotSupportedException; 030import java.time.Duration; 031import java.util.Collection; 032import java.util.Collections; 033import java.util.List; 034import java.util.Objects; 035import java.util.Properties; 036import java.util.Set; 037import java.util.function.BiConsumer; 038import java.util.logging.Logger; 039import java.util.stream.Collectors; 040import java.util.stream.Stream; 041 042import javax.management.MBeanRegistration; 043import javax.management.MBeanServer; 044import javax.management.MalformedObjectNameException; 045import javax.management.NotCompliantMBeanException; 046import javax.management.ObjectName; 047import javax.management.StandardMBean; 048import javax.sql.DataSource; 049 050import org.apache.commons.logging.Log; 051import org.apache.commons.logging.LogFactory; 052import org.apache.commons.pool2.PooledObject; 053import org.apache.commons.pool2.impl.AbandonedConfig; 054import org.apache.commons.pool2.impl.BaseObjectPoolConfig; 055import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig; 056import org.apache.commons.pool2.impl.GenericObjectPool; 057import org.apache.commons.pool2.impl.GenericObjectPoolConfig; 058 059/** 060 * Basic implementation of {@code javax.sql.DataSource} that is configured via JavaBeans properties. 061 * 062 * <p> 063 * This is not the only way to combine the <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a 064 * one-stop solution for basic requirements. 065 * </p> 066 * 067 * @since 2.0 068 */ 069public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBeanRegistration, AutoCloseable { 070 071 private static final Log log = LogFactory.getLog(BasicDataSource.class); 072 073 static { 074 // Attempt to prevent deadlocks - see DBCP - 272 075 DriverManager.getDrivers(); 076 try { 077 // Load classes now to prevent AccessControlExceptions later 078 // A number of classes are loaded when getConnection() is called 079 // but the following classes are not loaded and therefore require 080 // explicit loading. 081 if (Utils.isSecurityEnabled()) { 082 final ClassLoader loader = BasicDataSource.class.getClassLoader(); 083 final String dbcpPackageName = BasicDataSource.class.getPackage().getName(); 084 loader.loadClass(dbcpPackageName + ".DelegatingCallableStatement"); 085 loader.loadClass(dbcpPackageName + ".DelegatingDatabaseMetaData"); 086 loader.loadClass(dbcpPackageName + ".DelegatingPreparedStatement"); 087 loader.loadClass(dbcpPackageName + ".DelegatingResultSet"); 088 loader.loadClass(dbcpPackageName + ".PoolableCallableStatement"); 089 loader.loadClass(dbcpPackageName + ".PoolablePreparedStatement"); 090 loader.loadClass(dbcpPackageName + ".PoolingConnection$StatementType"); 091 loader.loadClass(dbcpPackageName + ".PStmtKey"); 092 093 final String poolPackageName = PooledObject.class.getPackage().getName(); 094 loader.loadClass(poolPackageName + ".impl.LinkedBlockingDeque$Node"); 095 loader.loadClass(poolPackageName + ".impl.GenericKeyedObjectPool$ObjectDeque"); 096 } 097 } catch (final ClassNotFoundException cnfe) { 098 throw new IllegalStateException("Unable to pre-load classes", cnfe); 099 } 100 } 101 102 /** 103 * Validates the given factory. 104 * 105 * @param connectionFactory the factory 106 * @throws SQLException Thrown by one of the factory methods while managing a temporary pooled object. 107 */ 108 @SuppressWarnings("resource") 109 protected static void validateConnectionFactory(final PoolableConnectionFactory connectionFactory) throws SQLException { 110 PoolableConnection conn = null; 111 PooledObject<PoolableConnection> p = null; 112 try { 113 p = connectionFactory.makeObject(); 114 conn = p.getObject(); 115 connectionFactory.activateObject(p); 116 connectionFactory.validateConnection(conn); 117 connectionFactory.passivateObject(p); 118 } finally { 119 if (p != null) { 120 connectionFactory.destroyObject(p); 121 } 122 } 123 } 124 125 /** 126 * The default auto-commit state of connections created by this pool. 127 */ 128 private volatile Boolean defaultAutoCommit; 129 130 /** 131 * The default read-only state of connections created by this pool. 132 */ 133 private transient Boolean defaultReadOnly; 134 135 /** 136 * The default TransactionIsolation state of connections created by this pool. 137 */ 138 private volatile int defaultTransactionIsolation = PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION; 139 140 private Duration defaultQueryTimeoutDuration; 141 142 /** 143 * The default "catalog" of connections created by this pool. 144 */ 145 private volatile String defaultCatalog; 146 147 /** 148 * The default "schema" of connections created by this pool. 149 */ 150 private volatile String defaultSchema; 151 152 /** 153 * The property that controls if the pooled connections cache some state rather than query the database for current 154 * state to improve performance. 155 */ 156 private boolean cacheState = true; 157 158 /** 159 * The instance of the JDBC Driver to use. 160 */ 161 private Driver driver; 162 163 /** 164 * The fully qualified Java class name of the JDBC driver to be used. 165 */ 166 private String driverClassName; 167 168 /** 169 * The class loader instance to use to load the JDBC driver. If not specified, {@link Class#forName(String)} is used 170 * to load the JDBC driver. If specified, {@link Class#forName(String, boolean, ClassLoader)} is used. 171 */ 172 private ClassLoader driverClassLoader; 173 174 /** 175 * True means that borrowObject returns the most recently used ("last in") connection in the pool (if there are idle 176 * connections available). False means that the pool behaves as a FIFO queue - connections are taken from the idle 177 * instance pool in the order that they are returned to the pool. 178 */ 179 private boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO; 180 181 /** 182 * The maximum number of active connections that can be allocated from this pool at the same time, or negative for 183 * no limit. 184 */ 185 private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL; 186 187 /** 188 * The maximum number of connections that can remain idle in the pool, without extra ones being destroyed, or 189 * negative for no limit. If maxIdle is set too low on heavily loaded systems it is possible you will see 190 * connections being closed and almost immediately new connections being opened. This is a result of the active 191 * threads momentarily closing connections faster than they are opening them, causing the number of idle connections 192 * to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good 193 * starting point. 194 */ 195 private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE; 196 197 /** 198 * The minimum number of active connections that can remain idle in the pool, without extra ones being created when 199 * the evictor runs, or 0 to create none. The pool attempts to ensure that minIdle connections are available when 200 * the idle object evictor runs. The value of this property has no effect unless 201 * {@link #durationBetweenEvictionRuns} has a positive value. 202 */ 203 private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE; 204 205 /** 206 * The initial number of connections that are created when the pool is started. 207 */ 208 private int initialSize; 209 210 /** 211 * The maximum Duration that the pool will wait (when there are no available connections) for a 212 * connection to be returned before throwing an exception, or <= 0 to wait indefinitely. 213 */ 214 private Duration maxWaitDuration = BaseObjectPoolConfig.DEFAULT_MAX_WAIT; 215 216 /** 217 * Prepared statement pooling for this pool. When this property is set to {@code true} both PreparedStatements 218 * and CallableStatements are pooled. 219 */ 220 private boolean poolPreparedStatements; 221 222 private boolean clearStatementPoolOnReturn; 223 224 /** 225 * <p> 226 * The maximum number of open statements that can be allocated from the statement pool at the same time, or negative 227 * for no limit. Since a connection usually only uses one or two statements at a time, this is mostly used to help 228 * detect resource leaks. 229 * </p> 230 * <p> 231 * Note: As of version 1.3, CallableStatements (those produced by {@link Connection#prepareCall}) are pooled along 232 * with PreparedStatements (produced by {@link Connection#prepareStatement}) and 233 * {@code maxOpenPreparedStatements} limits the total number of prepared or callable statements that may be in 234 * use at a given time. 235 * </p> 236 */ 237 private int maxOpenPreparedStatements = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL; 238 239 /** 240 * The indication of whether objects will be validated as soon as they have been created by the pool. If the object 241 * fails to validate, the borrow operation that triggered the creation will fail. 242 */ 243 private boolean testOnCreate; 244 245 /** 246 * The indication of whether objects will be validated before being borrowed from the pool. If the object fails to 247 * validate, it will be dropped from the pool, and we will attempt to borrow another. 248 */ 249 private boolean testOnBorrow = true; 250 251 /** 252 * The indication of whether objects will be validated before being returned to the pool. 253 */ 254 private boolean testOnReturn; 255 256 /** 257 * The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle 258 * object evictor thread will be run. 259 */ 260 private Duration durationBetweenEvictionRuns = BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS; 261 262 /** 263 * The number of objects to examine during each run of the idle object evictor thread (if any). 264 */ 265 private int numTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; 266 267 /** 268 * The minimum amount of time an object may sit idle in the pool before it is eligible for eviction by the idle 269 * object evictor (if any). 270 */ 271 private Duration minEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION; 272 273 /** 274 * The minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the idle 275 * object evictor, with the extra condition that at least "minIdle" connections remain in the pool. Note that 276 * {@code minEvictableIdleTimeMillis} takes precedence over this parameter. See 277 * {@link #getSoftMinEvictableIdleDuration()}. 278 */ 279 private Duration softMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION; 280 281 private String evictionPolicyClassName = BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME; 282 283 /** 284 * The indication of whether objects will be validated by the idle object evictor (if any). If an object fails to 285 * validate, it will be dropped from the pool. 286 */ 287 private boolean testWhileIdle; 288 289 /** 290 * The connection password to be passed to our JDBC driver to establish a connection. 291 */ 292 private volatile String password; 293 294 /** 295 * The connection string to be passed to our JDBC driver to establish a connection. 296 */ 297 private String connectionString; 298 299 /** 300 * The connection user name to be passed to our JDBC driver to establish a connection. 301 */ 302 private String userName; 303 304 /** 305 * The SQL query that will be used to validate connections from this pool before returning them to the caller. If 306 * specified, this query <strong>MUST</strong> be an SQL SELECT statement that returns at least one row. If not 307 * specified, {@link Connection#isValid(int)} will be used to validate connections. 308 */ 309 private volatile String validationQuery; 310 311 /** 312 * Timeout in seconds before connection validation queries fail. 313 */ 314 private volatile Duration validationQueryTimeoutDuration = Duration.ofSeconds(-1); 315 316 /** 317 * The fully qualified Java class name of a {@link ConnectionFactory} implementation. 318 */ 319 private String connectionFactoryClassName; 320 321 /** 322 * These SQL statements run once after a Connection is created. 323 * <p> 324 * This property can be used for example to run ALTER SESSION SET NLS_SORT=XCYECH in an Oracle Database only once 325 * after connection creation. 326 * </p> 327 */ 328 private volatile List<String> connectionInitSqls; 329 330 /** 331 * Controls access to the underlying connection. 332 */ 333 private boolean accessToUnderlyingConnectionAllowed; 334 335 private Duration maxConnDuration = Duration.ofMillis(-1); 336 337 private boolean logExpiredConnections = true; 338 339 private String jmxName; 340 341 private boolean registerConnectionMBean = true; 342 343 private boolean autoCommitOnReturn = true; 344 345 private boolean rollbackOnReturn = true; 346 347 private volatile Set<String> disconnectionSqlCodes; 348 349 private boolean fastFailValidation; 350 351 /** 352 * The object pool that internally manages our connections. 353 */ 354 private volatile GenericObjectPool<PoolableConnection> connectionPool; 355 356 /** 357 * The connection properties that will be sent to our JDBC driver when establishing new connections. 358 * <strong>NOTE</strong> - The "user" and "password" properties will be passed explicitly, so they do not need to be 359 * included here. 360 */ 361 private Properties connectionProperties = new Properties(); 362 363 /** 364 * The data source we will use to manage connections. This object should be acquired <strong>ONLY</strong> by calls 365 * to the {@code createDataSource()} method. 366 */ 367 private volatile DataSource dataSource; 368 369 /** 370 * The PrintWriter to which log messages should be directed. 371 */ 372 private volatile PrintWriter logWriter = new PrintWriter( 373 new OutputStreamWriter(System.out, StandardCharsets.UTF_8)); 374 375 private AbandonedConfig abandonedConfig; 376 377 private boolean closed; 378 379 /** 380 * Actual name under which this component has been registered. 381 */ 382 private ObjectNameWrapper registeredJmxObjectName; 383 384 /** 385 * Adds a custom connection property to the set that will be passed to our JDBC driver. This <strong>MUST</strong> 386 * be called before the first connection is retrieved (along with all the other configuration property setters). 387 * Calls to this method after the connection pool has been initialized have no effect. 388 * 389 * @param name Name of the custom connection property 390 * @param value Value of the custom connection property 391 */ 392 public void addConnectionProperty(final String name, final String value) { 393 connectionProperties.put(name, value); 394 } 395 396 /** 397 * Closes and releases all idle connections that are currently stored in the connection pool associated with this 398 * data source. 399 * <p> 400 * Connections that are checked out to clients when this method is invoked are not affected. When client 401 * applications subsequently invoke {@link Connection#close()} to return these connections to the pool, the 402 * underlying JDBC connections are closed. 403 * </p> 404 * <p> 405 * Attempts to acquire connections using {@link #getConnection()} after this method has been invoked result in 406 * SQLExceptions. To reopen a datasource that has been closed using this method, use {@link #start()}. 407 * </p> 408 * <p> 409 * This method is idempotent - i.e., closing an already closed BasicDataSource has no effect and does not generate 410 * exceptions. 411 * </p> 412 * 413 * @throws SQLException if an error occurs closing idle connections 414 */ 415 @Override 416 public synchronized void close() throws SQLException { 417 if (registeredJmxObjectName != null) { 418 registeredJmxObjectName.unregisterMBean(); 419 registeredJmxObjectName = null; 420 } 421 closed = true; 422 final GenericObjectPool<?> oldPool = connectionPool; 423 connectionPool = null; 424 dataSource = null; 425 try { 426 if (oldPool != null) { 427 oldPool.close(); 428 } 429 } catch (final RuntimeException e) { 430 throw e; 431 } catch (final Exception e) { 432 throw new SQLException(Utils.getMessage("pool.close.fail"), e); 433 } 434 } 435 436 /** 437 * Closes the connection pool, silently swallowing any exception that occurs. 438 */ 439 private void closeConnectionPool() { 440 final GenericObjectPool<?> oldPool = connectionPool; 441 connectionPool = null; 442 Utils.closeQuietly(oldPool); 443 } 444 445 /** 446 * Creates a JDBC connection factory for this data source. The JDBC driver is loaded using the following algorithm: 447 * <ol> 448 * <li>If a Driver instance has been specified via {@link #setDriver(Driver)} use it</li> 449 * <li>If no Driver instance was specified and {code driverClassName} is specified that class is loaded using the 450 * {@link ClassLoader} of this class or, if {code driverClassLoader} is set, {code driverClassName} is loaded 451 * with the specified {@link ClassLoader}.</li> 452 * <li>If {code driverClassName} is specified and the previous attempt fails, the class is loaded using the 453 * context class loader of the current thread.</li> 454 * <li>If a driver still isn't loaded one is loaded via the {@link DriverManager} using the specified {code connectionString}. 455 * </ol> 456 * <p> 457 * This method exists so subclasses can replace the implementation class. 458 * </p> 459 * 460 * @return A new connection factory. 461 * 462 * @throws SQLException If the connection factory cannot be created 463 */ 464 protected ConnectionFactory createConnectionFactory() throws SQLException { 465 // Load the JDBC driver class 466 return ConnectionFactoryFactory.createConnectionFactory(this, DriverFactory.createDriver(this)); 467 } 468 469 470 /** 471 * Creates a connection pool for this datasource. This method only exists so subclasses can replace the 472 * implementation class. 473 * <p> 474 * This implementation configures all pool properties other than timeBetweenEvictionRunsMillis. Setting that 475 * property is deferred to {@link #startPoolMaintenance()}, since setting timeBetweenEvictionRunsMillis to a 476 * positive value causes {@link GenericObjectPool}'s eviction timer to be started. 477 * </p> 478 * 479 * @param factory The factory to use to create new connections for this pool. 480 */ 481 protected void createConnectionPool(final PoolableConnectionFactory factory) { 482 // Create an object pool to contain our active connections 483 final GenericObjectPoolConfig<PoolableConnection> config = new GenericObjectPoolConfig<>(); 484 updateJmxName(config); 485 // Disable JMX on the underlying pool if the DS is not registered: 486 config.setJmxEnabled(registeredJmxObjectName != null); 487 final GenericObjectPool<PoolableConnection> gop = createObjectPool(factory, config, abandonedConfig); 488 gop.setMaxTotal(maxTotal); 489 gop.setMaxIdle(maxIdle); 490 gop.setMinIdle(minIdle); 491 gop.setMaxWait(maxWaitDuration); 492 gop.setTestOnCreate(testOnCreate); 493 gop.setTestOnBorrow(testOnBorrow); 494 gop.setTestOnReturn(testOnReturn); 495 gop.setNumTestsPerEvictionRun(numTestsPerEvictionRun); 496 gop.setMinEvictableIdleDuration(minEvictableIdleDuration); 497 gop.setSoftMinEvictableIdleDuration(softMinEvictableIdleDuration); 498 gop.setTestWhileIdle(testWhileIdle); 499 gop.setLifo(lifo); 500 gop.setSwallowedExceptionListener(new SwallowedExceptionLogger(log, logExpiredConnections)); 501 gop.setEvictionPolicyClassName(evictionPolicyClassName); 502 factory.setPool(gop); 503 connectionPool = gop; 504 } 505 506 /** 507 * Creates (if necessary) and return the internal data source we are using to manage our connections. 508 * 509 * @return The current internal DataSource or a newly created instance if it has not yet been created. 510 * @throws SQLException if the object pool cannot be created. 511 */ 512 protected synchronized DataSource createDataSource() throws SQLException { 513 if (closed) { 514 throw new SQLException("Data source is closed"); 515 } 516 517 // Return the pool if we have already created it 518 // This is double-checked locking. This is safe since dataSource is 519 // volatile and the code is targeted at Java 5 onwards. 520 if (dataSource != null) { 521 return dataSource; 522 } 523 synchronized (this) { 524 if (dataSource != null) { 525 return dataSource; 526 } 527 jmxRegister(); 528 529 // create factory which returns raw physical connections 530 final ConnectionFactory driverConnectionFactory = createConnectionFactory(); 531 532 // Set up the poolable connection factory 533 final PoolableConnectionFactory poolableConnectionFactory; 534 try { 535 poolableConnectionFactory = createPoolableConnectionFactory(driverConnectionFactory); 536 poolableConnectionFactory.setPoolStatements(poolPreparedStatements); 537 poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements); 538 // create a pool for our connections 539 createConnectionPool(poolableConnectionFactory); 540 final DataSource newDataSource = createDataSourceInstance(); 541 newDataSource.setLogWriter(logWriter); 542 connectionPool.addObjects(initialSize); 543 // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor 544 // task 545 startPoolMaintenance(); 546 dataSource = newDataSource; 547 } catch (final SQLException | RuntimeException se) { 548 closeConnectionPool(); 549 throw se; 550 } catch (final Exception ex) { 551 closeConnectionPool(); 552 throw new SQLException("Error creating connection factory", ex); 553 } 554 555 return dataSource; 556 } 557 } 558 559 /** 560 * Creates the actual data source instance. This method only exists so that subclasses can replace the 561 * implementation class. 562 * 563 * @throws SQLException if unable to create a datasource instance 564 * 565 * @return A new DataSource instance 566 */ 567 protected DataSource createDataSourceInstance() throws SQLException { 568 final PoolingDataSource<PoolableConnection> pds = new PoolingDataSource<>(connectionPool); 569 pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed()); 570 return pds; 571 } 572 573 /** 574 * Creates an object pool used to provide pooling support for {@link Connection JDBC connections}. 575 * 576 * @param factory the object factory 577 * @param poolConfig the object pool configuration 578 * @param abandonedConfig the abandoned objects configuration 579 * @return a non-null instance 580 */ 581 protected GenericObjectPool<PoolableConnection> createObjectPool(final PoolableConnectionFactory factory, 582 final GenericObjectPoolConfig<PoolableConnection> poolConfig, final AbandonedConfig abandonedConfig) { 583 final GenericObjectPool<PoolableConnection> gop; 584 if (abandonedConfig != null && (abandonedConfig.getRemoveAbandonedOnBorrow() 585 || abandonedConfig.getRemoveAbandonedOnMaintenance())) { 586 gop = new GenericObjectPool<>(factory, poolConfig, abandonedConfig); 587 } else { 588 gop = new GenericObjectPool<>(factory, poolConfig); 589 } 590 return gop; 591 } 592 593 /** 594 * Creates the PoolableConnectionFactory and attaches it to the connection pool. This method only exists so 595 * subclasses can replace the default implementation. 596 * 597 * @param driverConnectionFactory JDBC connection factory 598 * @throws SQLException if an error occurs creating the PoolableConnectionFactory 599 * 600 * @return A new PoolableConnectionFactory configured with the current configuration of this BasicDataSource 601 */ 602 protected PoolableConnectionFactory createPoolableConnectionFactory(final ConnectionFactory driverConnectionFactory) 603 throws SQLException { 604 PoolableConnectionFactory connectionFactory = null; 605 try { 606 if (registerConnectionMBean) { 607 connectionFactory = new PoolableConnectionFactory(driverConnectionFactory, ObjectNameWrapper.unwrap(registeredJmxObjectName)); 608 } else { 609 connectionFactory = new PoolableConnectionFactory(driverConnectionFactory, null); 610 } 611 connectionFactory.setValidationQuery(validationQuery); 612 connectionFactory.setValidationQueryTimeout(validationQueryTimeoutDuration); 613 connectionFactory.setConnectionInitSql(connectionInitSqls); 614 connectionFactory.setDefaultReadOnly(defaultReadOnly); 615 connectionFactory.setDefaultAutoCommit(defaultAutoCommit); 616 connectionFactory.setDefaultTransactionIsolation(defaultTransactionIsolation); 617 connectionFactory.setDefaultCatalog(defaultCatalog); 618 connectionFactory.setDefaultSchema(defaultSchema); 619 connectionFactory.setCacheState(cacheState); 620 connectionFactory.setPoolStatements(poolPreparedStatements); 621 connectionFactory.setClearStatementPoolOnReturn(clearStatementPoolOnReturn); 622 connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements); 623 connectionFactory.setMaxConn(maxConnDuration); 624 connectionFactory.setRollbackOnReturn(getRollbackOnReturn()); 625 connectionFactory.setAutoCommitOnReturn(getAutoCommitOnReturn()); 626 connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeoutDuration()); 627 connectionFactory.setFastFailValidation(fastFailValidation); 628 connectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes); 629 validateConnectionFactory(connectionFactory); 630 } catch (final RuntimeException e) { 631 throw e; 632 } catch (final Exception e) { 633 throw new SQLException("Cannot create PoolableConnectionFactory (" + e.getMessage() + ")", e); 634 } 635 return connectionFactory; 636 } 637 638 /** 639 * Manually evicts idle connections 640 * 641 * @throws Exception when there is a problem evicting idle objects. 642 */ 643 public void evict() throws Exception { 644 if (connectionPool != null) { 645 connectionPool.evict(); 646 } 647 } 648 649 /** 650 * Gets the print writer used by this configuration to log information on abandoned objects. 651 * 652 * @return The print writer used by this configuration to log information on abandoned objects. 653 */ 654 public PrintWriter getAbandonedLogWriter() { 655 return abandonedConfig == null ? null : abandonedConfig.getLogWriter(); 656 } 657 658 /** 659 * If the connection pool implements {@link org.apache.commons.pool2.UsageTracking UsageTracking}, should the 660 * connection pool record a stack trace every time a method is called on a pooled connection and retain the most 661 * recent stack trace to aid debugging of abandoned connections? 662 * 663 * @return {@code true} if usage tracking is enabled 664 */ 665 @Override 666 public boolean getAbandonedUsageTracking() { 667 return abandonedConfig != null && abandonedConfig.getUseUsageTracking(); 668 } 669 670 /** 671 * Gets the value of the flag that controls whether or not connections being returned to the pool will be checked 672 * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit 673 * setting is {@code false} when the connection is returned. It is {@code true} by default. 674 * 675 * @return Whether or not connections being returned to the pool will be checked and configured with auto-commit. 676 */ 677 public boolean getAutoCommitOnReturn() { 678 return autoCommitOnReturn; 679 } 680 681 /** 682 * Gets the state caching flag. 683 * 684 * @return the state caching flag 685 */ 686 @Override 687 public boolean getCacheState() { 688 return cacheState; 689 } 690 691 /** 692 * Creates (if necessary) and return a connection to the database. 693 * 694 * @throws SQLException if a database access error occurs 695 * @return a database connection 696 */ 697 @Override 698 public Connection getConnection() throws SQLException { 699 if (Utils.isSecurityEnabled()) { 700 final PrivilegedExceptionAction<Connection> action = () -> createDataSource().getConnection(); 701 try { 702 return AccessController.doPrivileged(action); 703 } catch (final PrivilegedActionException e) { 704 final Throwable cause = e.getCause(); 705 if (cause instanceof SQLException) { 706 throw (SQLException) cause; 707 } 708 throw new SQLException(e); 709 } 710 } 711 return createDataSource().getConnection(); 712 } 713 714 /** 715 * <strong>BasicDataSource does NOT support this method.</strong> 716 * 717 * @param user Database user on whose behalf the Connection is being made 718 * @param pass The database user's password 719 * 720 * @throws UnsupportedOperationException always thrown. 721 * @throws SQLException if a database access error occurs 722 * @return nothing - always throws UnsupportedOperationException 723 */ 724 @Override 725 public Connection getConnection(final String user, final String pass) throws SQLException { 726 // This method isn't supported by the PoolingDataSource returned by the 727 // createDataSource 728 throw new UnsupportedOperationException("Not supported by BasicDataSource"); 729 } 730 731 /** 732 * Gets the ConnectionFactoryClassName that has been configured for use by this pool. 733 * <p> 734 * Note: This getter only returns the last value set by a call to {@link #setConnectionFactoryClassName(String)}. 735 * </p> 736 * 737 * @return the ConnectionFactoryClassName that has been configured for use by this pool. 738 * @since 2.7.0 739 */ 740 public String getConnectionFactoryClassName() { 741 return this.connectionFactoryClassName; 742 } 743 744 /** 745 * Gets the list of SQL statements executed when a physical connection is first created. Returns an empty list if 746 * there are no initialization statements configured. 747 * 748 * @return initialization SQL statements 749 */ 750 public List<String> getConnectionInitSqls() { 751 final List<String> result = connectionInitSqls; 752 return result == null ? Collections.emptyList() : result; 753 } 754 755 /** 756 * Provides the same data as {@link #getConnectionInitSqls()} but in an array so it is accessible via JMX. 757 */ 758 @Override 759 public String[] getConnectionInitSqlsAsArray() { 760 return getConnectionInitSqls().toArray(Utils.EMPTY_STRING_ARRAY); 761 } 762 763 /** 764 * Gets the underlying connection pool. 765 * 766 * @return the underlying connection pool. 767 * @since 2.10.0 768 */ 769 public GenericObjectPool<PoolableConnection> getConnectionPool() { 770 return connectionPool; 771 } 772 773 Properties getConnectionProperties() { 774 return connectionProperties; 775 } 776 777 /** 778 * Gets the default auto-commit property. 779 * 780 * @return true if default auto-commit is enabled 781 */ 782 @Override 783 public Boolean getDefaultAutoCommit() { 784 return defaultAutoCommit; 785 } 786 787 /** 788 * Gets the default catalog. 789 * 790 * @return the default catalog 791 */ 792 @Override 793 public String getDefaultCatalog() { 794 return this.defaultCatalog; 795 } 796 797 /** 798 * Gets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this 799 * connection. {@code null} means that the driver default will be used. 800 * 801 * @return The default query timeout in seconds. 802 * @deprecated Use {@link #getDefaultQueryTimeoutDuration()}. 803 */ 804 @Deprecated 805 public Integer getDefaultQueryTimeout() { 806 return defaultQueryTimeoutDuration == null ? null : (int) defaultQueryTimeoutDuration.getSeconds(); 807 } 808 809 /** 810 * Gets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this 811 * connection. {@code null} means that the driver default will be used. 812 * 813 * @return The default query timeout Duration. 814 * @since 2.10.0 815 */ 816 public Duration getDefaultQueryTimeoutDuration() { 817 return defaultQueryTimeoutDuration; 818 } 819 820 /** 821 * Gets the default readOnly property. 822 * 823 * @return true if connections are readOnly by default 824 */ 825 @Override 826 public Boolean getDefaultReadOnly() { 827 return defaultReadOnly; 828 } 829 830 /** 831 * Gets the default schema. 832 * 833 * @return the default schema. 834 * @since 2.5.0 835 */ 836 @Override 837 public String getDefaultSchema() { 838 return this.defaultSchema; 839 } 840 841 /** 842 * Gets the default transaction isolation state of returned connections. 843 * 844 * @return the default value for transaction isolation state 845 * @see Connection#getTransactionIsolation 846 */ 847 @Override 848 public int getDefaultTransactionIsolation() { 849 return this.defaultTransactionIsolation; 850 } 851 852 /** 853 * Gets the set of SQL_STATE codes considered to signal fatal conditions. 854 * 855 * @return fatal disconnection state codes 856 * @see #setDisconnectionSqlCodes(Collection) 857 * @since 2.1 858 */ 859 public Set<String> getDisconnectionSqlCodes() { 860 final Set<String> result = disconnectionSqlCodes; 861 return result == null ? Collections.emptySet() : result; 862 } 863 864 /** 865 * Provides the same data as {@link #getDisconnectionSqlCodes} but in an array so it is accessible via JMX. 866 * 867 * @since 2.1 868 */ 869 @Override 870 public String[] getDisconnectionSqlCodesAsArray() { 871 return getDisconnectionSqlCodes().toArray(Utils.EMPTY_STRING_ARRAY); 872 } 873 874 /** 875 * Gets the JDBC Driver that has been configured for use by this pool. 876 * <p> 877 * Note: This getter only returns the last value set by a call to {@link #setDriver(Driver)}. It does not return any 878 * driver instance that may have been created from the value set via {@link #setDriverClassName(String)}. 879 * </p> 880 * 881 * @return the JDBC Driver that has been configured for use by this pool 882 */ 883 public synchronized Driver getDriver() { 884 return driver; 885 } 886 887 /** 888 * Gets the class loader specified for loading the JDBC driver. Returns {@code null} if no class loader has 889 * been explicitly specified. 890 * <p> 891 * Note: This getter only returns the last value set by a call to {@link #setDriverClassLoader(ClassLoader)}. It 892 * does not return the class loader of any driver that may have been set via {@link #setDriver(Driver)}. 893 * </p> 894 * 895 * @return The class loader specified for loading the JDBC driver. 896 */ 897 public synchronized ClassLoader getDriverClassLoader() { 898 return this.driverClassLoader; 899 } 900 901 /** 902 * Gets the JDBC driver class name. 903 * <p> 904 * Note: This getter only returns the last value set by a call to {@link #setDriverClassName(String)}. It does not 905 * return the class name of any driver that may have been set via {@link #setDriver(Driver)}. 906 * </p> 907 * 908 * @return the JDBC driver class name 909 */ 910 @Override 911 public synchronized String getDriverClassName() { 912 return this.driverClassName; 913 } 914 915 /** 916 * Gets the value of the {code durationBetweenEvictionRuns} property. 917 * 918 * @return the time (in milliseconds) between evictor runs 919 * @see #setDurationBetweenEvictionRuns(Duration) 920 * @since 2.10.0 921 */ 922 public synchronized Duration getDurationBetweenEvictionRuns() { 923 return this.durationBetweenEvictionRuns; 924 } 925 926 /** 927 * Gets the value of the flag that controls whether or not connections being returned to the pool will be checked 928 * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit 929 * setting is {@code false} when the connection is returned. It is {@code true} by default. 930 * 931 * @return Whether or not connections being returned to the pool will be checked and configured with auto-commit. 932 * @deprecated Use {@link #getAutoCommitOnReturn()}. 933 */ 934 @Deprecated 935 public boolean getEnableAutoCommitOnReturn() { 936 return autoCommitOnReturn; 937 } 938 939 /** 940 * Gets the EvictionPolicy implementation in use with this connection pool. 941 * 942 * @return The EvictionPolicy implementation in use with this connection pool. 943 */ 944 public synchronized String getEvictionPolicyClassName() { 945 return evictionPolicyClassName; 946 } 947 948 /** 949 * True means that validation will fail immediately for connections that have previously thrown SQLExceptions with 950 * SQL_STATE indicating fatal disconnection errors. 951 * 952 * @return true if connections created by this datasource will fast fail validation. 953 * @see #setDisconnectionSqlCodes(Collection) 954 * @since 2.1 955 */ 956 @Override 957 public boolean getFastFailValidation() { 958 return fastFailValidation; 959 } 960 961 /** 962 * Gets the initial size of the connection pool. 963 * 964 * @return the number of connections created when the pool is initialized 965 */ 966 @Override 967 public synchronized int getInitialSize() { 968 return this.initialSize; 969 } 970 971 /** 972 * Gets the JMX name that has been requested for this DataSource. If the requested name is not valid, an 973 * alternative may be chosen. 974 * 975 * @return The JMX name that has been requested for this DataSource. 976 */ 977 public String getJmxName() { 978 return jmxName; 979 } 980 981 /** 982 * Gets the LIFO property. 983 * 984 * @return true if connection pool behaves as a LIFO queue. 985 */ 986 @Override 987 public synchronized boolean getLifo() { 988 return this.lifo; 989 } 990 991 /** 992 * Flag to log stack traces for application code which abandoned a Statement or Connection. 993 * <p> 994 * Defaults to false. 995 * </p> 996 * <p> 997 * Logging of abandoned Statements and Connections adds overhead for every Connection open or new Statement because 998 * a stack trace has to be generated. 999 * </p> 1000 */ 1001 @Override 1002 public boolean getLogAbandoned() { 1003 return abandonedConfig != null && abandonedConfig.getLogAbandoned(); 1004 } 1005 1006 /** 1007 * When {@link #getMaxConnDuration()} is set to limit connection lifetime, this property determines whether or 1008 * not log messages are generated when the pool closes connections due to maximum lifetime exceeded. 1009 * 1010 * @since 2.1 1011 */ 1012 @Override 1013 public boolean getLogExpiredConnections() { 1014 return logExpiredConnections; 1015 } 1016 1017 /** 1018 * <strong>BasicDataSource does NOT support this method.</strong> 1019 * 1020 * <p> 1021 * Gets the login timeout (in seconds) for connecting to the database. 1022 * </p> 1023 * <p> 1024 * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. 1025 * </p> 1026 * 1027 * @throws SQLException if a database access error occurs 1028 * @throws UnsupportedOperationException If the DataSource implementation does not support the login timeout 1029 * feature. 1030 * @return login timeout in seconds 1031 */ 1032 @Override 1033 public int getLoginTimeout() throws SQLException { 1034 // This method isn't supported by the PoolingDataSource returned by the createDataSource 1035 throw new UnsupportedOperationException("Not supported by BasicDataSource"); 1036 } 1037 1038 /** 1039 * Gets the log writer being used by this data source. 1040 * <p> 1041 * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. 1042 * </p> 1043 * 1044 * @throws SQLException if a database access error occurs 1045 * @return log writer in use 1046 */ 1047 @Override 1048 public PrintWriter getLogWriter() throws SQLException { 1049 return createDataSource().getLogWriter(); 1050 } 1051 1052 /** 1053 * Gets the maximum permitted duration of a connection. A value of zero or less indicates an 1054 * infinite lifetime. 1055 * @return the maximum permitted duration of a connection. 1056 * @since 2.10.0 1057 */ 1058 public Duration getMaxConnDuration() { 1059 return maxConnDuration; 1060 } 1061 1062 /** 1063 * Gets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 1064 * infinite lifetime. 1065 * @deprecated Use {@link #getMaxConnDuration()}. 1066 */ 1067 @Override 1068 @Deprecated 1069 public long getMaxConnLifetimeMillis() { 1070 return maxConnDuration.toMillis(); 1071 } 1072 1073 /** 1074 * Gets the maximum number of connections that can remain idle in the pool. Excess idle connections are destroyed 1075 * on return to the pool. 1076 * <p> 1077 * A negative value indicates that there is no limit 1078 * </p> 1079 * 1080 * @return the maximum number of idle connections 1081 */ 1082 @Override 1083 public synchronized int getMaxIdle() { 1084 return this.maxIdle; 1085 } 1086 1087 /** 1088 * Gets the value of the {@code maxOpenPreparedStatements} property. 1089 * 1090 * @return the maximum number of open statements 1091 */ 1092 @Override 1093 public synchronized int getMaxOpenPreparedStatements() { 1094 return this.maxOpenPreparedStatements; 1095 } 1096 1097 /** 1098 * Gets the maximum number of active connections that can be allocated at the same time. 1099 * <p> 1100 * A negative number means that there is no limit. 1101 * </p> 1102 * 1103 * @return the maximum number of active connections 1104 */ 1105 @Override 1106 public synchronized int getMaxTotal() { 1107 return this.maxTotal; 1108 } 1109 1110 /** 1111 * Gets the maximum Duration that the pool will wait for a connection to be returned before throwing an exception. A 1112 * value less than or equal to zero means the pool is set to wait indefinitely. 1113 * 1114 * @return the maxWaitDuration property value. 1115 * @since 2.10.0 1116 */ 1117 public synchronized Duration getMaxWaitDuration() { 1118 return this.maxWaitDuration; 1119 } 1120 1121 /** 1122 * Gets the maximum number of milliseconds that the pool will wait for a connection to be returned before 1123 * throwing an exception. A value less than or equal to zero means the pool is set to wait indefinitely. 1124 * 1125 * @return the maxWaitMillis property value. 1126 * @deprecated Use {@link #getMaxWaitDuration()}. 1127 */ 1128 @Deprecated 1129 @Override 1130 public synchronized long getMaxWaitMillis() { 1131 return this.maxWaitDuration.toMillis(); 1132 } 1133 1134 /** 1135 * Gets the {code minEvictableIdleDuration} property. 1136 * 1137 * @return the value of the {code minEvictableIdleDuration} property 1138 * @see #setMinEvictableIdle(Duration) 1139 * @since 2.10.0 1140 */ 1141 public synchronized Duration getMinEvictableIdleDuration() { 1142 return this.minEvictableIdleDuration; 1143 } 1144 1145 /** 1146 * Gets the {code minEvictableIdleDuration} property. 1147 * 1148 * @return the value of the {code minEvictableIdleDuration} property 1149 * @see #setMinEvictableIdle(Duration) 1150 * @deprecated Use {@link #getMinEvictableIdleDuration()}. 1151 */ 1152 @Deprecated 1153 @Override 1154 public synchronized long getMinEvictableIdleTimeMillis() { 1155 return this.minEvictableIdleDuration.toMillis(); 1156 } 1157 1158 /** 1159 * Gets the minimum number of idle connections in the pool. The pool attempts to ensure that minIdle connections 1160 * are available when the idle object evictor runs. The value of this property has no effect unless 1161 * {code durationBetweenEvictionRuns} has a positive value. 1162 * 1163 * @return the minimum number of idle connections 1164 * @see GenericObjectPool#getMinIdle() 1165 */ 1166 @Override 1167 public synchronized int getMinIdle() { 1168 return this.minIdle; 1169 } 1170 1171 /** 1172 * [Read Only] The current number of active connections that have been allocated from this data source. 1173 * 1174 * @return the current number of active connections 1175 */ 1176 @Override 1177 public int getNumActive() { 1178 // Copy reference to avoid NPE if close happens after null check 1179 final GenericObjectPool<PoolableConnection> pool = connectionPool; 1180 return pool == null ? 0 : pool.getNumActive(); 1181 } 1182 1183 /** 1184 * [Read Only] The current number of idle connections that are waiting to be allocated from this data source. 1185 * 1186 * @return the current number of idle connections 1187 */ 1188 @Override 1189 public int getNumIdle() { 1190 // Copy reference to avoid NPE if close happens after null check 1191 final GenericObjectPool<PoolableConnection> pool = connectionPool; 1192 return pool == null ? 0 : pool.getNumIdle(); 1193 } 1194 1195 /** 1196 * Gets the value of the {code numTestsPerEvictionRun} property. 1197 * 1198 * @return the number of objects to examine during idle object evictor runs 1199 * @see #setNumTestsPerEvictionRun(int) 1200 */ 1201 @Override 1202 public synchronized int getNumTestsPerEvictionRun() { 1203 return this.numTestsPerEvictionRun; 1204 } 1205 1206 @Override 1207 public Logger getParentLogger() throws SQLFeatureNotSupportedException { 1208 throw new SQLFeatureNotSupportedException(); 1209 } 1210 1211 /** 1212 * Gets the password passed to the JDBC driver to establish connections. 1213 * 1214 * @return the connection password 1215 * @deprecated Exposing passwords via JMX is an Information Exposure issue. 1216 */ 1217 @Deprecated 1218 @Override 1219 public String getPassword() { 1220 return this.password; 1221 } 1222 1223 /** 1224 * Gets the registered JMX ObjectName. 1225 * 1226 * @return the registered JMX ObjectName. 1227 */ 1228 protected ObjectName getRegisteredJmxName() { 1229 return ObjectNameWrapper.unwrap(registeredJmxObjectName); 1230 } 1231 1232 /** 1233 * Flag to remove abandoned connections if they exceed the removeAbandonedTimeout when borrowObject is invoked. 1234 * <p> 1235 * The default value is false. 1236 * </p> 1237 * <p> 1238 * If set to true a connection is considered abandoned and eligible for removal if it has not been used for more 1239 * than {@link #getRemoveAbandonedTimeoutDuration() removeAbandonedTimeout} seconds. 1240 * </p> 1241 * <p> 1242 * Abandoned connections are identified and removed when {@link #getConnection()} is invoked and all of the 1243 * following conditions hold: 1244 * </p> 1245 * <ul> 1246 * <li>{@link #getRemoveAbandonedOnBorrow()}</li> 1247 * <li>{@link #getNumActive()} > {@link #getMaxTotal()} - 3</li> 1248 * <li>{@link #getNumIdle()} < 2</li> 1249 * </ul> 1250 * 1251 * @see #getRemoveAbandonedTimeoutDuration() 1252 */ 1253 @Override 1254 public boolean getRemoveAbandonedOnBorrow() { 1255 return abandonedConfig != null && abandonedConfig.getRemoveAbandonedOnBorrow(); 1256 } 1257 1258 /** 1259 * Flag to remove abandoned connections if they exceed the removeAbandonedTimeout during pool maintenance. 1260 * <p> 1261 * The default value is false. 1262 * </p> 1263 * <p> 1264 * If set to true a connection is considered abandoned and eligible for removal if it has not been used for more 1265 * than {@link #getRemoveAbandonedTimeoutDuration() removeAbandonedTimeout} seconds. 1266 * </p> 1267 * 1268 * @see #getRemoveAbandonedTimeoutDuration() 1269 */ 1270 @Override 1271 public boolean getRemoveAbandonedOnMaintenance() { 1272 return abandonedConfig != null && abandonedConfig.getRemoveAbandonedOnMaintenance(); 1273 } 1274 1275 /** 1276 * Gets the timeout in seconds before an abandoned connection can be removed. 1277 * <p> 1278 * Creating a Statement, PreparedStatement or CallableStatement or using one of these to execute a query (using one 1279 * of the execute methods) resets the lastUsed property of the parent connection. 1280 * </p> 1281 * <p> 1282 * Abandoned connection cleanup happens when: 1283 * </p> 1284 * <ul> 1285 * <li>{@link #getRemoveAbandonedOnBorrow()} or {@link #getRemoveAbandonedOnMaintenance()} = true</li> 1286 * <li>{@link #getNumIdle() numIdle} < 2</li> 1287 * <li>{@link #getNumActive() numActive} > {@link #getMaxTotal() maxTotal} - 3</li> 1288 * </ul> 1289 * <p> 1290 * The default value is 300 seconds. 1291 * </p> 1292 * @deprecated Use {@link #getRemoveAbandonedTimeoutDuration()}. 1293 */ 1294 @Deprecated 1295 @Override 1296 public int getRemoveAbandonedTimeout() { 1297 return (int) getRemoveAbandonedTimeoutDuration().getSeconds(); 1298 } 1299 1300 /** 1301 * Gets the timeout before an abandoned connection can be removed. 1302 * <p> 1303 * Creating a Statement, PreparedStatement or CallableStatement or using one of these to execute a query (using one 1304 * of the execute methods) resets the lastUsed property of the parent connection. 1305 * </p> 1306 * <p> 1307 * Abandoned connection cleanup happens when: 1308 * </p> 1309 * <ul> 1310 * <li>{@link #getRemoveAbandonedOnBorrow()} or {@link #getRemoveAbandonedOnMaintenance()} = true</li> 1311 * <li>{@link #getNumIdle() numIdle} < 2</li> 1312 * <li>{@link #getNumActive() numActive} > {@link #getMaxTotal() maxTotal} - 3</li> 1313 * </ul> 1314 * <p> 1315 * The default value is 300 seconds. 1316 * </p> 1317 * @return Timeout before an abandoned connection can be removed. 1318 * @since 2.10.0 1319 */ 1320 public Duration getRemoveAbandonedTimeoutDuration() { 1321 return abandonedConfig == null ? Duration.ofSeconds(300) : abandonedConfig.getRemoveAbandonedTimeoutDuration(); 1322 } 1323 1324 /** 1325 * Gets the current value of the flag that controls whether a connection will be rolled back when it is returned to 1326 * the pool if auto commit is not enabled and the connection is not read only. 1327 * 1328 * @return whether a connection will be rolled back when it is returned to the pool. 1329 */ 1330 public boolean getRollbackOnReturn() { 1331 return rollbackOnReturn; 1332 } 1333 1334 /** 1335 * Gets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by 1336 * the idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. 1337 * <p> 1338 * When {@link #getMinEvictableIdleTimeMillis() minEvictableIdleTimeMillis} is set to a positive value, 1339 * minEvictableIdleTimeMillis is examined first by the idle connection evictor - i.e. when idle connections are 1340 * visited by the evictor, idle time is first compared against {@code minEvictableIdleTimeMillis} (without 1341 * considering the number of idle connections in the pool) and then against {@code softMinEvictableIdleTimeMillis}, 1342 * including the {@code minIdle}, constraint. 1343 * </p> 1344 * 1345 * @return minimum amount of time a connection may sit idle in the pool before it is eligible for eviction, assuming 1346 * there are minIdle idle connections in the pool 1347 * @since 2.10.0 1348 */ 1349 public synchronized Duration getSoftMinEvictableIdleDuration() { 1350 return softMinEvictableIdleDuration; 1351 } 1352 1353 /** 1354 * Gets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by 1355 * the idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. 1356 * <p> 1357 * When {@link #getMinEvictableIdleTimeMillis() minEvictableIdleTimeMillis} is set to a positive value, 1358 * minEvictableIdleTimeMillis is examined first by the idle connection evictor - i.e. when idle connections are 1359 * visited by the evictor, idle time is first compared against {@code minEvictableIdleTimeMillis} (without 1360 * considering the number of idle connections in the pool) and then against {@code softMinEvictableIdleTimeMillis}, 1361 * including the {@code minIdle}, constraint. 1362 * </p> 1363 * 1364 * @return minimum amount of time a connection may sit idle in the pool before it is eligible for eviction, assuming 1365 * there are minIdle idle connections in the pool 1366 * @deprecated Use {@link #getSoftMinEvictableIdleDuration()}. 1367 */ 1368 @Deprecated 1369 @Override 1370 public synchronized long getSoftMinEvictableIdleTimeMillis() { 1371 return softMinEvictableIdleDuration.toMillis(); 1372 } 1373 1374 /** 1375 * Gets the {code testOnBorrow} property. 1376 * 1377 * @return true if objects are validated before being borrowed from the pool 1378 * 1379 * @see #setTestOnBorrow(boolean) 1380 */ 1381 @Override 1382 public synchronized boolean getTestOnBorrow() { 1383 return this.testOnBorrow; 1384 } 1385 1386 /** 1387 * Gets the {code testOnCreate} property. 1388 * 1389 * @return true if objects are validated immediately after they are created by the pool 1390 * @see #setTestOnCreate(boolean) 1391 */ 1392 @Override 1393 public synchronized boolean getTestOnCreate() { 1394 return this.testOnCreate; 1395 } 1396 1397 /** 1398 * Gets the value of the {code testOnReturn} property. 1399 * 1400 * @return true if objects are validated before being returned to the pool 1401 * @see #setTestOnReturn(boolean) 1402 */ 1403 public synchronized boolean getTestOnReturn() { 1404 return this.testOnReturn; 1405 } 1406 1407 /** 1408 * Gets the value of the {code testWhileIdle} property. 1409 * 1410 * @return true if objects examined by the idle object evictor are validated 1411 * @see #setTestWhileIdle(boolean) 1412 */ 1413 @Override 1414 public synchronized boolean getTestWhileIdle() { 1415 return this.testWhileIdle; 1416 } 1417 1418 /** 1419 * Gets the value of the {code durationBetweenEvictionRuns} property. 1420 * 1421 * @return the time (in milliseconds) between evictor runs 1422 * @see #setDurationBetweenEvictionRuns(Duration) 1423 * @deprecated Use {@link #getDurationBetweenEvictionRuns()}. 1424 */ 1425 @Deprecated 1426 @Override 1427 public synchronized long getTimeBetweenEvictionRunsMillis() { 1428 return this.durationBetweenEvictionRuns.toMillis(); 1429 } 1430 1431 /** 1432 * Gets the JDBC connection {code connectionString} property. 1433 * 1434 * @return the {code connectionString} passed to the JDBC driver to establish connections 1435 */ 1436 @Override 1437 public synchronized String getUrl() { 1438 return this.connectionString; 1439 } 1440 1441 /** 1442 * Gets the JDBC connection {code userName} property. 1443 * 1444 * @return the {code userName} passed to the JDBC driver to establish connections 1445 * @deprecated 1446 */ 1447 @Deprecated 1448 @Override 1449 public String getUsername() { 1450 return this.userName; 1451 } 1452 1453 /** 1454 * Gets the validation query used to validate connections before returning them. 1455 * 1456 * @return the SQL validation query 1457 * @see #setValidationQuery(String) 1458 */ 1459 @Override 1460 public String getValidationQuery() { 1461 return this.validationQuery; 1462 } 1463 1464 /** 1465 * Gets the validation query timeout. 1466 * 1467 * @return the timeout in seconds before connection validation queries fail. 1468 * @deprecated Use {@link #getValidationQueryTimeoutDuration()}. 1469 */ 1470 @Deprecated 1471 @Override 1472 public int getValidationQueryTimeout() { 1473 return (int) validationQueryTimeoutDuration.getSeconds(); 1474 } 1475 1476 /** 1477 * Gets the validation query timeout. 1478 * 1479 * @return the timeout in seconds before connection validation queries fail. 1480 */ 1481 public Duration getValidationQueryTimeoutDuration() { 1482 return validationQueryTimeoutDuration; 1483 } 1484 1485 /** 1486 * Manually invalidates a connection, effectively requesting the pool to try to close it, remove it from the pool 1487 * and reclaim pool capacity. 1488 * 1489 * @param connection The Connection to invalidate. 1490 * 1491 * @throws IllegalStateException if invalidating the connection failed. 1492 * @since 2.1 1493 */ 1494 @SuppressWarnings("resource") 1495 public void invalidateConnection(final Connection connection) throws IllegalStateException { 1496 if (connection == null) { 1497 return; 1498 } 1499 if (connectionPool == null) { 1500 throw new IllegalStateException("Cannot invalidate connection: ConnectionPool is null."); 1501 } 1502 1503 final PoolableConnection poolableConnection; 1504 try { 1505 poolableConnection = connection.unwrap(PoolableConnection.class); 1506 if (poolableConnection == null) { 1507 throw new IllegalStateException( 1508 "Cannot invalidate connection: Connection is not a poolable connection."); 1509 } 1510 } catch (final SQLException e) { 1511 throw new IllegalStateException("Cannot invalidate connection: Unwrapping poolable connection failed.", e); 1512 } 1513 1514 try { 1515 connectionPool.invalidateObject(poolableConnection); 1516 } catch (final Exception e) { 1517 throw new IllegalStateException("Invalidating connection threw unexpected exception", e); 1518 } 1519 } 1520 1521 /** 1522 * Gets the value of the accessToUnderlyingConnectionAllowed property. 1523 * 1524 * @return true if access to the underlying connection is allowed, false otherwise. 1525 */ 1526 @Override 1527 public synchronized boolean isAccessToUnderlyingConnectionAllowed() { 1528 return this.accessToUnderlyingConnectionAllowed; 1529 } 1530 1531 /** 1532 * Returns true if the statement pool is cleared when the connection is returned to its pool. 1533 * 1534 * @return true if the statement pool is cleared at connection return 1535 * @since 2.8.0 1536 */ 1537 @Override 1538 public boolean isClearStatementPoolOnReturn() { 1539 return clearStatementPoolOnReturn; 1540 } 1541 1542 /** 1543 * If true, this data source is closed and no more connections can be retrieved from this data source. 1544 * 1545 * @return true, if the data source is closed; false otherwise 1546 */ 1547 @Override 1548 public synchronized boolean isClosed() { 1549 return closed; 1550 } 1551 1552 /** 1553 * Delegates in a null-safe manner to {@link String#isEmpty()}. 1554 * 1555 * @param value the string to test, may be null. 1556 * @return boolean false if value is null, otherwise {@link String#isEmpty()}. 1557 */ 1558 private boolean isEmpty(final String value) { 1559 return value == null || value.trim().isEmpty(); 1560 } 1561 1562 /** 1563 * Returns true if we are pooling statements. 1564 * 1565 * @return true if prepared and callable statements are pooled 1566 */ 1567 @Override 1568 public synchronized boolean isPoolPreparedStatements() { 1569 return this.poolPreparedStatements; 1570 } 1571 1572 @Override 1573 public boolean isWrapperFor(final Class<?> iface) throws SQLException { 1574 return iface != null && iface.isInstance(this); 1575 } 1576 1577 private void jmxRegister() { 1578 // Return immediately if this DataSource has already been registered 1579 if (registeredJmxObjectName != null) { 1580 return; 1581 } 1582 // Return immediately if no JMX name has been specified 1583 final String requestedName = getJmxName(); 1584 if (requestedName == null) { 1585 return; 1586 } 1587 registeredJmxObjectName = registerJmxObjectName(requestedName, null); 1588 try { 1589 final StandardMBean standardMBean = new StandardMBean(this, DataSourceMXBean.class); 1590 registeredJmxObjectName.registerMBean(standardMBean); 1591 } catch (final NotCompliantMBeanException e) { 1592 log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored."); 1593 } 1594 } 1595 1596 /** 1597 * Logs the given message. 1598 * 1599 * @param message the message to log. 1600 */ 1601 protected void log(final String message) { 1602 if (logWriter != null) { 1603 logWriter.println(message); 1604 } 1605 } 1606 1607 /** 1608 * Logs the given throwable. 1609 * @param message TODO 1610 * @param throwable the throwable. 1611 * 1612 * @since 2.7.0 1613 */ 1614 protected void log(final String message, final Throwable throwable) { 1615 if (logWriter != null) { 1616 logWriter.println(message); 1617 throwable.printStackTrace(logWriter); 1618 } 1619 } 1620 1621 @Override 1622 public void postDeregister() { 1623 // NO-OP 1624 } 1625 1626 @Override 1627 public void postRegister(final Boolean registrationDone) { 1628 // NO-OP 1629 } 1630 1631 @Override 1632 public void preDeregister() throws Exception { 1633 // NO-OP 1634 } 1635 1636 @Override 1637 public ObjectName preRegister(final MBeanServer server, final ObjectName objectName) { 1638 registeredJmxObjectName = registerJmxObjectName(getJmxName(), objectName); 1639 return ObjectNameWrapper.unwrap(registeredJmxObjectName); 1640 } 1641 1642 private ObjectNameWrapper registerJmxObjectName(final String requestedName, final ObjectName objectName) { 1643 ObjectNameWrapper objectNameWrapper = null; 1644 if (requestedName != null) { 1645 try { 1646 objectNameWrapper = ObjectNameWrapper.wrap(requestedName); 1647 } catch (final MalformedObjectNameException e) { 1648 log.warn("The requested JMX name '" + requestedName + "' was not valid and will be ignored."); 1649 } 1650 } 1651 if (objectNameWrapper == null) { 1652 objectNameWrapper = ObjectNameWrapper.wrap(objectName); 1653 } 1654 return objectNameWrapper; 1655 } 1656 1657 /** 1658 * Removes a custom connection property. 1659 * 1660 * @param name Name of the custom connection property to remove 1661 * @see #addConnectionProperty(String, String) 1662 */ 1663 public void removeConnectionProperty(final String name) { 1664 connectionProperties.remove(name); 1665 } 1666 1667 /** 1668 * Restarts the datasource. 1669 * <p> 1670 * This method calls {@link #close()} and {@link #start()} in sequence within synchronized scope so any 1671 * connection requests that come in while the datasource is shutting down will be served by the new pool. 1672 * <p> 1673 * Idle connections that are stored in the connection pool when this method is invoked are closed, but 1674 * connections that are checked out to clients when this method is invoked are not affected. When client 1675 * applications subsequently invoke {@link Connection#close()} to return these connections to the pool, the 1676 * underlying JDBC connections are closed. These connections do not count in {@link #getMaxTotal()} or 1677 * {@link #getNumActive()} after invoking this method. For example, if there are 3 connections checked out by 1678 * clients when {@link #restart()} is invoked, after this method is called, {@link #getNumActive()} will 1679 * return 0 and up to {@link #getMaxTotal()} + 3 connections may be open until the connections sourced from 1680 * the original pool are returned. 1681 * <p> 1682 * The new connection pool created by this method is initialized with currently set configuration properties. 1683 * 1684 * @throws SQLException if an error occurs initializing the datasource 1685 */ 1686 @Override 1687 public synchronized void restart() throws SQLException { 1688 close(); 1689 start(); 1690 } 1691 1692 private <T> void setAbandoned(final BiConsumer<AbandonedConfig, T> consumer, final T object) { 1693 if (abandonedConfig == null) { 1694 abandonedConfig = new AbandonedConfig(); 1695 } 1696 consumer.accept(abandonedConfig, object); 1697 final GenericObjectPool<?> gop = this.connectionPool; 1698 if (gop != null) { 1699 gop.setAbandonedConfig(abandonedConfig); 1700 } 1701 } 1702 1703 /** 1704 * Sets the print writer to be used by this configuration to log information on abandoned objects. 1705 * 1706 * @param logWriter The new log writer 1707 */ 1708 public void setAbandonedLogWriter(final PrintWriter logWriter) { 1709 setAbandoned(AbandonedConfig::setLogWriter, logWriter); 1710 } 1711 1712 /** 1713 * If the connection pool implements {@link org.apache.commons.pool2.UsageTracking UsageTracking}, configure whether 1714 * the connection pool should record a stack trace every time a method is called on a pooled connection and retain 1715 * the most recent stack trace to aid debugging of abandoned connections. 1716 * 1717 * @param usageTracking A value of {@code true} will enable the recording of a stack trace on every use of a 1718 * pooled connection 1719 */ 1720 public void setAbandonedUsageTracking(final boolean usageTracking) { 1721 setAbandoned(AbandonedConfig::setUseUsageTracking, usageTracking); 1722 } 1723 1724 /** 1725 * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to 1726 * the underlying connection. (Default: false) 1727 * <p> 1728 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1729 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1730 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1731 * </p> 1732 * 1733 * @param allow Access to the underlying connection is granted when true. 1734 */ 1735 public synchronized void setAccessToUnderlyingConnectionAllowed(final boolean allow) { 1736 this.accessToUnderlyingConnectionAllowed = allow; 1737 } 1738 1739 /** 1740 * Sets the value of the flag that controls whether or not connections being returned to the pool will be checked 1741 * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit 1742 * setting is {@code false} when the connection is returned. It is {@code true} by default. 1743 * 1744 * @param autoCommitOnReturn Whether or not connections being returned to the pool will be checked and configured 1745 * with auto-commit. 1746 * @since 2.6.0 1747 */ 1748 public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) { 1749 this.autoCommitOnReturn = autoCommitOnReturn; 1750 } 1751 1752 /** 1753 * Sets the state caching flag. 1754 * 1755 * @param cacheState The new value for the state caching flag 1756 */ 1757 public void setCacheState(final boolean cacheState) { 1758 this.cacheState = cacheState; 1759 } 1760 1761 /** 1762 * Sets whether the pool of statements (which was enabled with {@link #setPoolPreparedStatements(boolean)}) should 1763 * be cleared when the connection is returned to its pool. Default is false. 1764 * 1765 * @param clearStatementPoolOnReturn clear or not 1766 * @since 2.8.0 1767 */ 1768 public void setClearStatementPoolOnReturn(final boolean clearStatementPoolOnReturn) { 1769 this.clearStatementPoolOnReturn = clearStatementPoolOnReturn; 1770 } 1771 1772 /** 1773 * Sets the ConnectionFactory class name. 1774 * 1775 * @param connectionFactoryClassName A class name. 1776 * @since 2.7.0 1777 */ 1778 public void setConnectionFactoryClassName(final String connectionFactoryClassName) { 1779 this.connectionFactoryClassName = isEmpty(connectionFactoryClassName) ? null : connectionFactoryClassName; 1780 } 1781 1782 /** 1783 * Sets the list of SQL statements to be executed when a physical connection is first created. 1784 * <p> 1785 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1786 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1787 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1788 * </p> 1789 * 1790 * @param connectionInitSqls Collection of SQL statements to execute on connection creation 1791 */ 1792 public void setConnectionInitSqls(final Collection<String> connectionInitSqls) { 1793// if (connectionInitSqls != null && !connectionInitSqls.isEmpty()) { 1794// ArrayList<String> newVal = null; 1795// for (final String s : connectionInitSqls) { 1796// if (!isEmpty(s)) { 1797// if (newVal == null) { 1798// newVal = new ArrayList<>(); 1799// } 1800// newVal.add(s); 1801// } 1802// } 1803// this.connectionInitSqls = newVal; 1804// } else { 1805// this.connectionInitSqls = null; 1806// } 1807 final List<String> collect = Utils.isEmpty(connectionInitSqls) ? null 1808 : connectionInitSqls.stream().filter(s -> !isEmpty(s)).collect(Collectors.toList()); 1809 this.connectionInitSqls = Utils.isEmpty(collect) ? null : collect; 1810 } 1811 1812 private <T> void setConnectionPool(final BiConsumer<GenericObjectPool<PoolableConnection>, T> consumer, final T object) { 1813 if (connectionPool != null) { 1814 consumer.accept(connectionPool, object); 1815 } 1816 } 1817 1818 /** 1819 * Sets the connection properties passed to driver.connect(...). 1820 * <p> 1821 * Format of the string must be [propertyName=property;]* 1822 * </p> 1823 * <p> 1824 * NOTE - The "user" and "password" properties will be added explicitly, so they do not need to be included here. 1825 * </p> 1826 * 1827 * @param connectionProperties the connection properties used to create new connections 1828 */ 1829 public void setConnectionProperties(final String connectionProperties) { 1830 Objects.requireNonNull(connectionProperties, "connectionProperties"); 1831 final String[] entries = connectionProperties.split(";"); 1832 final Properties properties = new Properties(); 1833 Stream.of(entries).filter(e -> !e.isEmpty()).forEach(entry -> { 1834 final int index = entry.indexOf('='); 1835 if (index > 0) { 1836 final String name = entry.substring(0, index); 1837 final String value = entry.substring(index + 1); 1838 properties.setProperty(name, value); 1839 } else { 1840 // no value is empty string which is how 1841 // java.util.Properties works 1842 properties.setProperty(entry, ""); 1843 } 1844 }); 1845 this.connectionProperties = properties; 1846 } 1847 1848 /** 1849 * Sets default auto-commit state of connections returned by this datasource. 1850 * <p> 1851 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1852 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1853 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1854 * </p> 1855 * 1856 * @param defaultAutoCommit default auto-commit value 1857 */ 1858 public void setDefaultAutoCommit(final Boolean defaultAutoCommit) { 1859 this.defaultAutoCommit = defaultAutoCommit; 1860 } 1861 1862 /** 1863 * Sets the default catalog. 1864 * <p> 1865 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1866 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1867 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1868 * </p> 1869 * 1870 * @param defaultCatalog the default catalog 1871 */ 1872 public void setDefaultCatalog(final String defaultCatalog) { 1873 this.defaultCatalog = isEmpty(defaultCatalog) ? null : defaultCatalog; 1874 } 1875 1876 /** 1877 * Sets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this 1878 * connection. {@code null} means that the driver default will be used. 1879 * 1880 * @param defaultQueryTimeoutDuration The default query timeout Duration. 1881 * @since 2.10.0 1882 */ 1883 public void setDefaultQueryTimeout(final Duration defaultQueryTimeoutDuration) { 1884 this.defaultQueryTimeoutDuration = defaultQueryTimeoutDuration; 1885 } 1886 1887 /** 1888 * Sets the default query timeout that will be used for {@link java.sql.Statement Statement}s created from this 1889 * connection. {@code null} means that the driver default will be used. 1890 * 1891 * @param defaultQueryTimeoutSeconds The default query timeout in seconds. 1892 * @deprecated Use {@link #setDefaultQueryTimeout(Duration)}. 1893 */ 1894 @Deprecated 1895 public void setDefaultQueryTimeout(final Integer defaultQueryTimeoutSeconds) { 1896 this.defaultQueryTimeoutDuration = defaultQueryTimeoutSeconds == null ? null : Duration.ofSeconds(defaultQueryTimeoutSeconds); 1897 } 1898 1899 /** 1900 * Sets defaultReadonly property. 1901 * <p> 1902 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1903 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1904 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1905 * </p> 1906 * 1907 * @param defaultReadOnly default read-only value 1908 */ 1909 public void setDefaultReadOnly(final Boolean defaultReadOnly) { 1910 this.defaultReadOnly = defaultReadOnly; 1911 } 1912 1913 /** 1914 * Sets the default schema. 1915 * <p> 1916 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1917 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1918 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1919 * </p> 1920 * 1921 * @param defaultSchema the default catalog 1922 * @since 2.5.0 1923 */ 1924 public void setDefaultSchema(final String defaultSchema) { 1925 this.defaultSchema = isEmpty(defaultSchema) ? null : defaultSchema; 1926 } 1927 1928 /** 1929 * Sets the default transaction isolation state for returned connections. 1930 * <p> 1931 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1932 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1933 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1934 * </p> 1935 * 1936 * @param defaultTransactionIsolation the default transaction isolation state 1937 * @see Connection#getTransactionIsolation 1938 */ 1939 public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) { 1940 this.defaultTransactionIsolation = defaultTransactionIsolation; 1941 } 1942 1943 /** 1944 * Sets the SQL_STATE codes considered to signal fatal conditions. 1945 * <p> 1946 * Overrides the defaults in {@link Utils#getDisconnectionSqlCodes()} (plus anything starting with 1947 * {@link Utils#DISCONNECTION_SQL_CODE_PREFIX}). If this property is non-null and {@link #getFastFailValidation()} 1948 * is {@code true}, whenever connections created by this datasource generate exceptions with SQL_STATE codes in this 1949 * list, they will be marked as "fatally disconnected" and subsequent validations will fail fast (no attempt at 1950 * isValid or validation query). 1951 * </p> 1952 * <p> 1953 * If {@link #getFastFailValidation()} is {@code false} setting this property has no effect. 1954 * </p> 1955 * <p> 1956 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1957 * time one of the following methods is invoked: {@code getConnection, setLogwriter, 1958 * setLoginTimeout, getLoginTimeout, getLogWriter}. 1959 * </p> 1960 * 1961 * @param disconnectionSqlCodes SQL_STATE codes considered to signal fatal conditions 1962 * @since 2.1 1963 */ 1964 public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) { 1965// if (disconnectionSqlCodes != null && !disconnectionSqlCodes.isEmpty()) { 1966// HashSet<String> newVal = null; 1967// for (final String s : disconnectionSqlCodes) { 1968// if (!isEmpty(s)) { 1969// if (newVal == null) { 1970// newVal = new HashSet<>(); 1971// } 1972// newVal.add(s); 1973// } 1974// } 1975// this.disconnectionSqlCodes = newVal; 1976// } else { 1977// this.disconnectionSqlCodes = null; 1978// } 1979 final Set<String> collect = Utils.isEmpty(disconnectionSqlCodes) ? null 1980 : disconnectionSqlCodes.stream().filter(s -> !isEmpty(s)).collect(Collectors.toSet()); 1981 this.disconnectionSqlCodes = Utils.isEmpty(collect) ? null : collect; 1982 } 1983 1984 /** 1985 * Sets the JDBC Driver instance to use for this pool. 1986 * <p> 1987 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1988 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1989 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1990 * </p> 1991 * 1992 * @param driver The JDBC Driver instance to use for this pool. 1993 */ 1994 public synchronized void setDriver(final Driver driver) { 1995 this.driver = driver; 1996 } 1997 1998 /** 1999 * Sets the class loader to be used to load the JDBC driver. 2000 * <p> 2001 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2002 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2003 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2004 * </p> 2005 * 2006 * @param driverClassLoader the class loader with which to load the JDBC driver 2007 */ 2008 public synchronized void setDriverClassLoader(final ClassLoader driverClassLoader) { 2009 this.driverClassLoader = driverClassLoader; 2010 } 2011 2012 /** 2013 * Sets the JDBC driver class name. 2014 * <p> 2015 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2016 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2017 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2018 * </p> 2019 * 2020 * @param driverClassName the class name of the JDBC driver 2021 */ 2022 public synchronized void setDriverClassName(final String driverClassName) { 2023 this.driverClassName = isEmpty(driverClassName) ? null : driverClassName; 2024 } 2025 2026 /** 2027 * Sets the {code durationBetweenEvictionRuns} property. 2028 * 2029 * @param timeBetweenEvictionRunsMillis the new time between evictor runs 2030 * @see #setDurationBetweenEvictionRuns(Duration) 2031 * @since 2.10.0 2032 */ 2033 public synchronized void setDurationBetweenEvictionRuns(final Duration timeBetweenEvictionRunsMillis) { 2034 this.durationBetweenEvictionRuns = timeBetweenEvictionRunsMillis; 2035 setConnectionPool(GenericObjectPool::setDurationBetweenEvictionRuns, timeBetweenEvictionRunsMillis); 2036 } 2037 2038 /** 2039 * Sets the value of the flag that controls whether or not connections being returned to the pool will be checked 2040 * and configured with {@link Connection#setAutoCommit(boolean) Connection.setAutoCommit(true)} if the auto commit 2041 * setting is {@code false} when the connection is returned. It is {@code true} by default. 2042 * 2043 * @param autoCommitOnReturn Whether or not connections being returned to the pool will be checked and configured 2044 * with auto-commit. 2045 * @deprecated Use {@link #setAutoCommitOnReturn(boolean)}. 2046 */ 2047 @Deprecated 2048 public void setEnableAutoCommitOnReturn(final boolean autoCommitOnReturn) { 2049 this.autoCommitOnReturn = autoCommitOnReturn; 2050 } 2051 2052 /** 2053 * Sets the EvictionPolicy implementation to use with this connection pool. 2054 * 2055 * @param evictionPolicyClassName The fully qualified class name of the EvictionPolicy implementation 2056 */ 2057 public synchronized void setEvictionPolicyClassName(final String evictionPolicyClassName) { 2058 setConnectionPool(GenericObjectPool::setEvictionPolicyClassName, evictionPolicyClassName); 2059 this.evictionPolicyClassName = evictionPolicyClassName; 2060 } 2061 2062 /** 2063 * @see #getFastFailValidation() 2064 * @param fastFailValidation true means connections created by this factory will fast fail validation 2065 * @since 2.1 2066 */ 2067 public void setFastFailValidation(final boolean fastFailValidation) { 2068 this.fastFailValidation = fastFailValidation; 2069 } 2070 2071 /** 2072 * Sets the initial size of the connection pool. 2073 * <p> 2074 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2075 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2076 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2077 * </p> 2078 * 2079 * @param initialSize the number of connections created when the pool is initialized 2080 */ 2081 public synchronized void setInitialSize(final int initialSize) { 2082 this.initialSize = initialSize; 2083 } 2084 2085 /** 2086 * Sets the JMX name that has been requested for this DataSource. If the requested name is not valid, an alternative 2087 * may be chosen. This DataSource will attempt to register itself using this name. If another component registers 2088 * this DataSource with JMX and this name is valid this name will be used in preference to any specified by the 2089 * other component. 2090 * 2091 * @param jmxName The JMX name that has been requested for this DataSource 2092 */ 2093 public void setJmxName(final String jmxName) { 2094 this.jmxName = jmxName; 2095 } 2096 2097 /** 2098 * Sets the LIFO property. True means the pool behaves as a LIFO queue; false means FIFO. 2099 * 2100 * @param lifo the new value for the LIFO property 2101 */ 2102 public synchronized void setLifo(final boolean lifo) { 2103 this.lifo = lifo; 2104 setConnectionPool(GenericObjectPool::setLifo, lifo); 2105 } 2106 2107 /** 2108 * @param logAbandoned new logAbandoned property value 2109 */ 2110 public void setLogAbandoned(final boolean logAbandoned) { 2111 setAbandoned(AbandonedConfig::setLogAbandoned, logAbandoned); 2112 } 2113 2114 /** 2115 * When {@link #getMaxConnDuration()} is set to limit connection lifetime, this property determines whether or 2116 * not log messages are generated when the pool closes connections due to maximum lifetime exceeded. Set this 2117 * property to false to suppress log messages when connections expire. 2118 * 2119 * @param logExpiredConnections Whether or not log messages are generated when the pool closes connections due to 2120 * maximum lifetime exceeded. 2121 */ 2122 public void setLogExpiredConnections(final boolean logExpiredConnections) { 2123 this.logExpiredConnections = logExpiredConnections; 2124 } 2125 2126 /** 2127 * <strong>BasicDataSource does NOT support this method. </strong> 2128 * 2129 * <p> 2130 * Set the login timeout (in seconds) for connecting to the database. 2131 * </p> 2132 * <p> 2133 * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. 2134 * </p> 2135 * 2136 * @param loginTimeout The new login timeout, or zero for no timeout 2137 * @throws UnsupportedOperationException If the DataSource implementation does not support the login timeout 2138 * feature. 2139 * @throws SQLException if a database access error occurs 2140 */ 2141 @Override 2142 public void setLoginTimeout(final int loginTimeout) throws SQLException { 2143 // This method isn't supported by the PoolingDataSource returned by the 2144 // createDataSource 2145 throw new UnsupportedOperationException("Not supported by BasicDataSource"); 2146 } 2147 2148 /** 2149 * Sets the log writer being used by this data source. 2150 * <p> 2151 * Calls {@link #createDataSource()}, so has the side effect of initializing the connection pool. 2152 * </p> 2153 * 2154 * @param logWriter The new log writer 2155 * @throws SQLException if a database access error occurs 2156 */ 2157 @Override 2158 public void setLogWriter(final PrintWriter logWriter) throws SQLException { 2159 createDataSource().setLogWriter(logWriter); 2160 this.logWriter = logWriter; 2161 } 2162 2163 /** 2164 * Sets the maximum permitted lifetime of a connection. A value of zero or less indicates an 2165 * infinite lifetime. 2166 * <p> 2167 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2168 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2169 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2170 * </p> 2171 * 2172 * @param maxConnDuration The maximum permitted lifetime of a connection. 2173 * @since 2.10.0 2174 */ 2175 public void setMaxConn(final Duration maxConnDuration) { 2176 this.maxConnDuration = maxConnDuration; 2177 } 2178 2179 /** 2180 * Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 2181 * infinite lifetime. 2182 * <p> 2183 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2184 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2185 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2186 * </p> 2187 * 2188 * @param maxConnLifetimeMillis The maximum permitted lifetime of a connection in milliseconds. 2189 * @deprecated Use {@link #setMaxConn(Duration)}. 2190 */ 2191 @Deprecated 2192 public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) { 2193 this.maxConnDuration = Duration.ofMillis(maxConnLifetimeMillis); 2194 } 2195 2196 /** 2197 * Sets the maximum number of connections that can remain idle in the pool. Excess idle connections are destroyed on 2198 * return to the pool. 2199 * 2200 * @see #getMaxIdle() 2201 * @param maxIdle the new value for maxIdle 2202 */ 2203 public synchronized void setMaxIdle(final int maxIdle) { 2204 this.maxIdle = maxIdle; 2205 setConnectionPool(GenericObjectPool::setMaxIdle, maxIdle); 2206 } 2207 2208 /** 2209 * Sets the value of the {@code maxOpenPreparedStatements} property. 2210 * <p> 2211 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2212 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2213 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2214 * </p> 2215 * 2216 * @param maxOpenStatements the new maximum number of prepared statements 2217 */ 2218 public synchronized void setMaxOpenPreparedStatements(final int maxOpenStatements) { 2219 this.maxOpenPreparedStatements = maxOpenStatements; 2220 } 2221 2222 /** 2223 * Sets the maximum total number of idle and borrows connections that can be active at the same time. Use a negative 2224 * value for no limit. 2225 * 2226 * @param maxTotal the new value for maxTotal 2227 * @see #getMaxTotal() 2228 */ 2229 public synchronized void setMaxTotal(final int maxTotal) { 2230 this.maxTotal = maxTotal; 2231 setConnectionPool(GenericObjectPool::setMaxTotal, maxTotal); 2232 } 2233 2234 /** 2235 * Sets the MaxWaitMillis property. Use -1 to make the pool wait indefinitely. 2236 * 2237 * @param maxWaitDuration the new value for MaxWaitMillis 2238 * @see #getMaxWaitDuration() 2239 * @since 2.10.0 2240 */ 2241 public synchronized void setMaxWait(final Duration maxWaitDuration) { 2242 this.maxWaitDuration = maxWaitDuration; 2243 setConnectionPool(GenericObjectPool::setMaxWait, maxWaitDuration); 2244 } 2245 2246 /** 2247 * Sets the MaxWaitMillis property. Use -1 to make the pool wait indefinitely. 2248 * 2249 * @param maxWaitMillis the new value for MaxWaitMillis 2250 * @see #getMaxWaitDuration() 2251 * @deprecated {@link #setMaxWait(Duration)}. 2252 */ 2253 @Deprecated 2254 public synchronized void setMaxWaitMillis(final long maxWaitMillis) { 2255 setMaxWait(Duration.ofMillis(maxWaitMillis)); 2256 } 2257 2258 /** 2259 * Sets the {code minEvictableIdleDuration} property. 2260 * 2261 * @param minEvictableIdleDuration the minimum amount of time an object may sit idle in the pool 2262 * @see #setMinEvictableIdle(Duration) 2263 * @since 2.10.0 2264 */ 2265 public synchronized void setMinEvictableIdle(final Duration minEvictableIdleDuration) { 2266 this.minEvictableIdleDuration = minEvictableIdleDuration; 2267 setConnectionPool(GenericObjectPool::setMinEvictableIdleDuration, minEvictableIdleDuration); 2268 } 2269 2270 /** 2271 * Sets the {code minEvictableIdleDuration} property. 2272 * 2273 * @param minEvictableIdleTimeMillis the minimum amount of time an object may sit idle in the pool 2274 * @see #setMinEvictableIdle(Duration) 2275 * @deprecated Use {@link #setMinEvictableIdle(Duration)}. 2276 */ 2277 @Deprecated 2278 public synchronized void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) { 2279 setMinEvictableIdle(Duration.ofMillis(minEvictableIdleTimeMillis)); 2280 } 2281 2282 /** 2283 * Sets the minimum number of idle connections in the pool. The pool attempts to ensure that minIdle connections are 2284 * available when the idle object evictor runs. The value of this property has no effect unless 2285 * {code durationBetweenEvictionRuns} has a positive value. 2286 * 2287 * @param minIdle the new value for minIdle 2288 * @see GenericObjectPool#setMinIdle(int) 2289 */ 2290 public synchronized void setMinIdle(final int minIdle) { 2291 this.minIdle = minIdle; 2292 setConnectionPool(GenericObjectPool::setMinIdle, minIdle); 2293 } 2294 2295 /** 2296 * Sets the value of the {code numTestsPerEvictionRun} property. 2297 * 2298 * @param numTestsPerEvictionRun the new {code numTestsPerEvictionRun} value 2299 * @see #setNumTestsPerEvictionRun(int) 2300 */ 2301 public synchronized void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) { 2302 this.numTestsPerEvictionRun = numTestsPerEvictionRun; 2303 setConnectionPool(GenericObjectPool::setNumTestsPerEvictionRun, numTestsPerEvictionRun); 2304 } 2305 2306 /** 2307 * Sets the {code password}. 2308 * <p> 2309 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2310 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2311 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2312 * </p> 2313 * 2314 * @param password new value for the password 2315 */ 2316 public void setPassword(final String password) { 2317 this.password = password; 2318 } 2319 2320 /** 2321 * Sets whether to pool statements or not. 2322 * <p> 2323 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2324 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2325 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2326 * </p> 2327 * 2328 * @param poolingStatements pooling on or off 2329 */ 2330 public synchronized void setPoolPreparedStatements(final boolean poolingStatements) { 2331 this.poolPreparedStatements = poolingStatements; 2332 } 2333 2334 /** 2335 * Sets if connection level JMX tracking is requested for this DataSource. If true, each connection will be 2336 * registered for tracking with JMX. 2337 * 2338 * @param registerConnectionMBean connection tracking requested for this DataSource. 2339 */ 2340 public void setRegisterConnectionMBean(final boolean registerConnectionMBean) { 2341 this.registerConnectionMBean = registerConnectionMBean; 2342 } 2343 2344 /** 2345 * @param removeAbandonedOnBorrow true means abandoned connections may be removed when connections are borrowed from 2346 * the pool. 2347 * @see #getRemoveAbandonedOnBorrow() 2348 */ 2349 public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) { 2350 setAbandoned(AbandonedConfig::setRemoveAbandonedOnBorrow, removeAbandonedOnBorrow); 2351 } 2352 2353 /** 2354 * @param removeAbandonedOnMaintenance true means abandoned connections may be removed on pool maintenance. 2355 * @see #getRemoveAbandonedOnMaintenance() 2356 */ 2357 public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) { 2358 setAbandoned(AbandonedConfig::setRemoveAbandonedOnMaintenance, removeAbandonedOnMaintenance); 2359 } 2360 2361 /** 2362 * Sets the timeout before an abandoned connection can be removed. 2363 * <p> 2364 * Setting this property has no effect if {@link #getRemoveAbandonedOnBorrow()} and 2365 * {code getRemoveAbandonedOnMaintenance()} are false. 2366 * </p> 2367 * 2368 * @param removeAbandonedTimeout new abandoned timeout 2369 * @see #getRemoveAbandonedTimeoutDuration() 2370 * @see #getRemoveAbandonedOnBorrow() 2371 * @see #getRemoveAbandonedOnMaintenance() 2372 * @since 2.10.0 2373 */ 2374 public void setRemoveAbandonedTimeout(final Duration removeAbandonedTimeout) { 2375 setAbandoned(AbandonedConfig::setRemoveAbandonedTimeout, removeAbandonedTimeout); 2376 } 2377 2378 /** 2379 * Sets the timeout in seconds before an abandoned connection can be removed. 2380 * <p> 2381 * Setting this property has no effect if {@link #getRemoveAbandonedOnBorrow()} and 2382 * {@link #getRemoveAbandonedOnMaintenance()} are false. 2383 * </p> 2384 * 2385 * @param removeAbandonedTimeout new abandoned timeout in seconds 2386 * @see #getRemoveAbandonedTimeoutDuration() 2387 * @see #getRemoveAbandonedOnBorrow() 2388 * @see #getRemoveAbandonedOnMaintenance() 2389 * @deprecated Use {@link #setRemoveAbandonedTimeout(Duration)}. 2390 */ 2391 @Deprecated 2392 public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) { 2393 setAbandoned(AbandonedConfig::setRemoveAbandonedTimeout, Duration.ofSeconds(removeAbandonedTimeout)); 2394 } 2395 2396 /** 2397 * Sets the flag that controls if a connection will be rolled back when it is returned to the pool if auto commit is 2398 * not enabled and the connection is not read only. 2399 * 2400 * @param rollbackOnReturn whether a connection will be rolled back when it is returned to the pool. 2401 */ 2402 public void setRollbackOnReturn(final boolean rollbackOnReturn) { 2403 this.rollbackOnReturn = rollbackOnReturn; 2404 } 2405 2406 /** 2407 * Sets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the 2408 * idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. 2409 * 2410 * @param softMinEvictableIdleTimeMillis minimum amount of time a connection may sit idle in the pool before it is 2411 * eligible for eviction, assuming there are minIdle idle connections in the 2412 * pool. 2413 * @see #getSoftMinEvictableIdleTimeMillis 2414 * @since 2.10.0 2415 */ 2416 public synchronized void setSoftMinEvictableIdle(final Duration softMinEvictableIdleTimeMillis) { 2417 this.softMinEvictableIdleDuration = softMinEvictableIdleTimeMillis; 2418 setConnectionPool(GenericObjectPool::setSoftMinEvictableIdleDuration, softMinEvictableIdleTimeMillis); 2419 } 2420 2421 /** 2422 * Sets the minimum amount of time a connection may sit idle in the pool before it is eligible for eviction by the 2423 * idle object evictor, with the extra condition that at least "minIdle" connections remain in the pool. 2424 * 2425 * @param softMinEvictableIdleTimeMillis minimum amount of time a connection may sit idle in the pool before it is 2426 * eligible for eviction, assuming there are minIdle idle connections in the 2427 * pool. 2428 * @see #getSoftMinEvictableIdleTimeMillis 2429 * @deprecated Use {@link #setSoftMinEvictableIdle(Duration)}. 2430 */ 2431 @Deprecated 2432 public synchronized void setSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) { 2433 setSoftMinEvictableIdle(Duration.ofMillis(softMinEvictableIdleTimeMillis)); 2434 } 2435 2436 /** 2437 * Sets the {code testOnBorrow} property. This property determines whether or not the pool will validate objects 2438 * before they are borrowed from the pool. 2439 * 2440 * @param testOnBorrow new value for testOnBorrow property 2441 */ 2442 public synchronized void setTestOnBorrow(final boolean testOnBorrow) { 2443 this.testOnBorrow = testOnBorrow; 2444 setConnectionPool(GenericObjectPool::setTestOnBorrow, testOnBorrow); 2445 } 2446 2447 /** 2448 * Sets the {code testOnCreate} property. This property determines whether or not the pool will validate objects 2449 * immediately after they are created by the pool 2450 * 2451 * @param testOnCreate new value for testOnCreate property 2452 */ 2453 public synchronized void setTestOnCreate(final boolean testOnCreate) { 2454 this.testOnCreate = testOnCreate; 2455 setConnectionPool(GenericObjectPool::setTestOnCreate, testOnCreate); 2456 } 2457 2458 /** 2459 * Sets the {@code testOnReturn} property. This property determines whether or not the pool will validate 2460 * objects before they are returned to the pool. 2461 * 2462 * @param testOnReturn new value for testOnReturn property 2463 */ 2464 public synchronized void setTestOnReturn(final boolean testOnReturn) { 2465 this.testOnReturn = testOnReturn; 2466 setConnectionPool(GenericObjectPool::setTestOnReturn, testOnReturn); 2467 } 2468 2469 /** 2470 * Sets the {@code testWhileIdle} property. This property determines whether or not the idle object evictor 2471 * will validate connections. 2472 * 2473 * @param testWhileIdle new value for testWhileIdle property 2474 */ 2475 public synchronized void setTestWhileIdle(final boolean testWhileIdle) { 2476 this.testWhileIdle = testWhileIdle; 2477 setConnectionPool(GenericObjectPool::setTestWhileIdle, testWhileIdle); 2478 } 2479 2480 /** 2481 * Sets the {code durationBetweenEvictionRuns} property. 2482 * 2483 * @param timeBetweenEvictionRunsMillis the new time between evictor runs 2484 * @see #setDurationBetweenEvictionRuns(Duration) 2485 * @deprecated Use {@link #setDurationBetweenEvictionRuns(Duration)}. 2486 */ 2487 @Deprecated 2488 public synchronized void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) { 2489 setDurationBetweenEvictionRuns(Duration.ofMillis(timeBetweenEvictionRunsMillis)); 2490 } 2491 2492 /** 2493 * Sets the {code connection string}. 2494 * <p> 2495 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2496 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2497 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2498 * </p> 2499 * 2500 * @param connectionString the new value for the JDBC connection connectionString 2501 */ 2502 public synchronized void setUrl(final String connectionString) { 2503 this.connectionString = connectionString; 2504 } 2505 2506 /** 2507 * Sets the {code userName}. 2508 * <p> 2509 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2510 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2511 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2512 * </p> 2513 * 2514 * @param userName the new value for the JDBC connection user name 2515 */ 2516 public void setUsername(final String userName) { 2517 this.userName = userName; 2518 } 2519 2520 /** 2521 * Sets the {code validationQuery}. 2522 * <p> 2523 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2524 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2525 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2526 * </p> 2527 * 2528 * @param validationQuery the new value for the validation query 2529 */ 2530 public void setValidationQuery(final String validationQuery) { 2531 this.validationQuery = isEmpty(validationQuery) ? null : validationQuery; 2532 } 2533 2534 /** 2535 * Sets the validation query timeout, the amount of time, in seconds, that connection validation will wait for a 2536 * response from the database when executing a validation query. Use a value less than or equal to 0 for no timeout. 2537 * <p> 2538 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2539 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2540 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2541 * </p> 2542 * 2543 * @param validationQueryTimeoutDuration new validation query timeout value in seconds 2544 * @since 2.10.0 2545 */ 2546 public void setValidationQueryTimeout(final Duration validationQueryTimeoutDuration) { 2547 this.validationQueryTimeoutDuration = validationQueryTimeoutDuration; 2548 } 2549 2550 /** 2551 * Sets the validation query timeout, the amount of time, in seconds, that connection validation will wait for a 2552 * response from the database when executing a validation query. Use a value less than or equal to 0 for no timeout. 2553 * <p> 2554 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 2555 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 2556 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 2557 * </p> 2558 * 2559 * @param validationQueryTimeoutSeconds new validation query timeout value in seconds 2560 * @deprecated Use {@link #setValidationQueryTimeout(Duration)}. 2561 */ 2562 @Deprecated 2563 public void setValidationQueryTimeout(final int validationQueryTimeoutSeconds) { 2564 this.validationQueryTimeoutDuration = Duration.ofSeconds(validationQueryTimeoutSeconds); 2565 } 2566 2567 /** 2568 * Starts the datasource. 2569 * <p> 2570 * It is not necessary to call this method before using a newly created BasicDataSource instance, but 2571 * calling it in that context causes the datasource to be immediately initialized (instead of waiting for 2572 * the first {@link #getConnection()} request). Its primary use is to restart and reinitialize a 2573 * datasource that has been closed. 2574 * <p> 2575 * When this method is called after {@link #close()}, connections checked out by clients 2576 * before the datasource was stopped do not count in {@link #getMaxTotal()} or {@link #getNumActive()}. 2577 * For example, if there are 3 connections checked out by clients when {@link #close()} is invoked and they are 2578 * not returned before {@link #start()} is invoked, after this method is called, {@link #getNumActive()} will 2579 * return 0. These connections will be physically closed when they are returned, but they will not count against 2580 * the maximum allowed in the newly started datasource. 2581 * 2582 * @throws SQLException if an error occurs initializing the datasource 2583 */ 2584 @Override 2585 public synchronized void start() throws SQLException { 2586 closed = false; 2587 createDataSource(); 2588 } 2589 2590 /** 2591 * Starts the connection pool maintenance task, if configured. 2592 */ 2593 protected void startPoolMaintenance() { 2594 if (connectionPool != null && durationBetweenEvictionRuns.compareTo(Duration.ZERO) > 0) { 2595 connectionPool.setDurationBetweenEvictionRuns(durationBetweenEvictionRuns); 2596 } 2597 } 2598 2599 @Override 2600 public <T> T unwrap(final Class<T> iface) throws SQLException { 2601 if (isWrapperFor(iface)) { 2602 return iface.cast(this); 2603 } 2604 throw new SQLException(this + " is not a wrapper for " + iface); 2605 } 2606 2607 private void updateJmxName(final GenericObjectPoolConfig<?> config) { 2608 if (registeredJmxObjectName == null) { 2609 return; 2610 } 2611 final StringBuilder base = new StringBuilder(registeredJmxObjectName.toString()); 2612 base.append(Constants.JMX_CONNECTION_POOL_BASE_EXT); 2613 config.setJmxNameBase(base.toString()); 2614 config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX); 2615 } 2616 2617}