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