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