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