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