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