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