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.datasources; 018 019import java.io.OutputStreamWriter; 020import java.io.PrintWriter; 021import java.io.Serializable; 022import java.nio.charset.StandardCharsets; 023import java.sql.Connection; 024import java.sql.SQLException; 025import java.sql.SQLFeatureNotSupportedException; 026import java.time.Duration; 027import java.util.Properties; 028import java.util.logging.Logger; 029 030import javax.naming.Context; 031import javax.naming.InitialContext; 032import javax.naming.Referenceable; 033import javax.sql.ConnectionPoolDataSource; 034import javax.sql.DataSource; 035import javax.sql.PooledConnection; 036 037import org.apache.commons.dbcp2.Utils; 038import org.apache.commons.pool2.impl.BaseObjectPoolConfig; 039import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig; 040import org.apache.commons.pool2.impl.GenericObjectPool; 041 042/** 043 * <p> 044 * The base class for {@code SharedPoolDataSource} and {@code PerUserPoolDataSource}. Many of the 045 * configuration properties are shared and defined here. This class is declared public in order to allow particular 046 * usage with commons-beanutils; do not make direct use of it outside of <em>commons-dbcp2</em>. 047 * </p> 048 * 049 * <p> 050 * A J2EE container will normally provide some method of initializing the {@code DataSource} whose attributes are 051 * presented as bean getters/setters and then deploying it via JNDI. It is then available to an application as a source 052 * of pooled logical connections to the database. The pool needs a source of physical connections. This source is in the 053 * form of a {@code ConnectionPoolDataSource} that can be specified via the {@link #setDataSourceName(String)} used 054 * to lookup the source via JNDI. 055 * </p> 056 * 057 * <p> 058 * Although normally used within a JNDI environment, A DataSource can be instantiated and initialized as any bean. In 059 * this case the {@code ConnectionPoolDataSource} will likely be instantiated in a similar manner. This class 060 * allows the physical source of connections to be attached directly to this pool using the 061 * {@link #setConnectionPoolDataSource(ConnectionPoolDataSource)} method. 062 * </p> 063 * 064 * <p> 065 * The dbcp package contains an adapter, {@link org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS}, that can be 066 * used to allow the use of {@code DataSource}'s based on this class with JDBC driver implementations that do not 067 * supply a {@code ConnectionPoolDataSource}, but still provide a {@link java.sql.Driver} implementation. 068 * </p> 069 * 070 * <p> 071 * The <a href="package-summary.html">package documentation</a> contains an example using Apache Tomcat and JNDI and it 072 * also contains a non-JNDI example. 073 * </p> 074 * 075 * @since 2.0 076 */ 077public abstract class InstanceKeyDataSource implements DataSource, Referenceable, Serializable, AutoCloseable { 078 079 private static final long serialVersionUID = -6819270431752240878L; 080 081 private static final String GET_CONNECTION_CALLED = "A Connection was already requested from this source, " 082 + "further initialization is not allowed."; 083 private static final String BAD_TRANSACTION_ISOLATION = "The requested TransactionIsolation level is invalid."; 084 085 /** 086 * Internal constant to indicate the level is not set. 087 */ 088 protected static final int UNKNOWN_TRANSACTIONISOLATION = -1; 089 090 /** Guards property setters - once true, setters throw IllegalStateException */ 091 private volatile boolean getConnectionCalled; 092 093 /** Underlying source of PooledConnections */ 094 private ConnectionPoolDataSource dataSource; 095 096 /** DataSource Name used to find the ConnectionPoolDataSource */ 097 private String dataSourceName; 098 099 /** Description */ 100 private String description; 101 102 /** Environment that may be used to set up a JNDI initial context. */ 103 private Properties jndiEnvironment; 104 105 /** Login Timeout */ 106 private Duration loginTimeoutDuration = Duration.ZERO; 107 108 /** Log stream */ 109 private PrintWriter logWriter; 110 111 /** Instance key */ 112 private String instanceKey; 113 114 // Pool properties 115 private boolean defaultBlockWhenExhausted = BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED; 116 private String defaultEvictionPolicyClassName = BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME; 117 private boolean defaultLifo = BaseObjectPoolConfig.DEFAULT_LIFO; 118 private int defaultMaxIdle = GenericKeyedObjectPoolConfig.DEFAULT_MAX_IDLE_PER_KEY; 119 private int defaultMaxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL; 120 private Duration defaultMaxWaitDuration = BaseObjectPoolConfig.DEFAULT_MAX_WAIT; 121 private Duration defaultMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION; 122 private int defaultMinIdle = GenericKeyedObjectPoolConfig.DEFAULT_MIN_IDLE_PER_KEY; 123 private int defaultNumTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; 124 private Duration defaultSoftMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION; 125 private boolean defaultTestOnCreate = BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE; 126 private boolean defaultTestOnBorrow = BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW; 127 private boolean defaultTestOnReturn = BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN; 128 private boolean defaultTestWhileIdle = BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE; 129 private Duration defaultDurationBetweenEvictionRuns = BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS; 130 131 // Connection factory properties 132 private String validationQuery; 133 private Duration validationQueryTimeoutDuration = Duration.ofSeconds(-1); 134 private boolean rollbackAfterValidation; 135 private Duration maxConnDuration = Duration.ofMillis(-1); 136 137 // Connection properties 138 private Boolean defaultAutoCommit; 139 private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION; 140 private Boolean defaultReadOnly; 141 142 /** 143 * Default no-arg constructor for Serialization. 144 */ 145 public InstanceKeyDataSource() { 146 } 147 148 /** 149 * Throws an IllegalStateException, if a PooledConnection has already been requested. 150 * 151 * @throws IllegalStateException Thrown if a PooledConnection has already been requested. 152 */ 153 protected void assertInitializationAllowed() throws IllegalStateException { 154 if (getConnectionCalled) { 155 throw new IllegalStateException(GET_CONNECTION_CALLED); 156 } 157 } 158 159 /** 160 * Closes the connection pool being maintained by this datasource. 161 */ 162 @Override 163 public abstract void close() throws SQLException; 164 165 private void closeDueToException(final PooledConnectionAndInfo info) { 166 if (info != null) { 167 try { 168 info.getPooledConnection().getConnection().close(); 169 } catch (final Exception e) { 170 // do not throw this exception because we are in the middle 171 // of handling another exception. But record it because 172 // it potentially leaks connections from the pool. 173 getLogWriter().println("[ERROR] Could not return connection to pool during exception handling. " + e.getMessage()); 174 } 175 } 176 } 177 178 /** 179 * Attempts to establish a database connection. 180 */ 181 @Override 182 public Connection getConnection() throws SQLException { 183 return getConnection(null, null); 184 } 185 186 /** 187 * Attempts to retrieve a database connection using {@link #getPooledConnectionAndInfo(String, String)} with the 188 * provided user name and password. The password on the {@code PooledConnectionAndInfo} instance returned by 189 * {@code getPooledConnectionAndInfo} is compared to the {@code password} parameter. If the comparison 190 * fails, a database connection using the supplied user name and password is attempted. If the connection attempt 191 * fails, an SQLException is thrown, indicating that the given password did not match the password used to create 192 * the pooled connection. If the connection attempt succeeds, this means that the database password has been 193 * changed. In this case, the {@code PooledConnectionAndInfo} instance retrieved with the old password is 194 * destroyed and the {@code getPooledConnectionAndInfo} is repeatedly invoked until a 195 * {@code PooledConnectionAndInfo} instance with the new password is returned. 196 */ 197 @Override 198 public Connection getConnection(final String userName, final String userPassword) throws SQLException { 199 if (instanceKey == null) { 200 throw new SQLException("Must set the ConnectionPoolDataSource " 201 + "through setDataSourceName or setConnectionPoolDataSource" + " before calling getConnection."); 202 } 203 getConnectionCalled = true; 204 PooledConnectionAndInfo info = null; 205 try { 206 info = getPooledConnectionAndInfo(userName, userPassword); 207 } catch (final RuntimeException | SQLException e) { 208 closeDueToException(info); 209 throw e; 210 } catch (final Exception e) { 211 closeDueToException(info); 212 throw new SQLException("Cannot borrow connection from pool", e); 213 } 214 215 // Password on PooledConnectionAndInfo does not match 216 if (!(null == userPassword ? null == info.getPassword() : userPassword.equals(info.getPassword()))) { 217 try { // See if password has changed by attempting connection 218 testCPDS(userName, userPassword); 219 } catch (final SQLException ex) { 220 // Password has not changed, so refuse client, but return connection to the pool 221 closeDueToException(info); 222 throw new SQLException( 223 "Given password did not match password used" + " to create the PooledConnection.", ex); 224 } catch (final javax.naming.NamingException ne) { 225 throw new SQLException("NamingException encountered connecting to database", ne); 226 } 227 /* 228 * Password must have changed -> destroy connection and keep retrying until we get a new, good one, 229 * destroying any idle connections with the old password as we pull them from the pool. 230 */ 231 final UserPassKey upkey = info.getUserPassKey(); 232 final PooledConnectionManager manager = getConnectionManager(upkey); 233 // Destroy and remove from pool 234 manager.invalidate(info.getPooledConnection()); 235 // Reset the password on the factory if using CPDSConnectionFactory 236 manager.setPassword(upkey.getPassword()); 237 info = null; 238 for (int i = 0; i < 10; i++) { // Bound the number of retries - only needed if bad instances return 239 try { 240 info = getPooledConnectionAndInfo(userName, userPassword); 241 } catch (final RuntimeException | SQLException e) { 242 closeDueToException(info); 243 throw e; 244 } catch (final Exception e) { 245 closeDueToException(info); 246 throw new SQLException("Cannot borrow connection from pool", e); 247 } 248 if (info != null && userPassword != null && userPassword.equals(info.getPassword())) { 249 break; 250 } 251 if (info != null) { 252 manager.invalidate(info.getPooledConnection()); 253 } 254 info = null; 255 } 256 if (info == null) { 257 throw new SQLException("Cannot borrow connection from pool - password change failure."); 258 } 259 } 260 261 final Connection connection = info.getPooledConnection().getConnection(); 262 try { 263 setupDefaults(connection, userName); 264 connection.clearWarnings(); 265 return connection; 266 } catch (final SQLException ex) { 267 Utils.close(connection, e -> getLogWriter().println("ignoring exception during close: " + e)); 268 throw ex; 269 } 270 } 271 272 protected abstract PooledConnectionManager getConnectionManager(UserPassKey upkey); 273 274 /** 275 * Gets the value of connectionPoolDataSource. This method will return null, if the backing data source is being 276 * accessed via JNDI. 277 * 278 * @return value of connectionPoolDataSource. 279 */ 280 public ConnectionPoolDataSource getConnectionPoolDataSource() { 281 return dataSource; 282 } 283 284 /** 285 * Gets the name of the ConnectionPoolDataSource which backs this pool. This name is used to look up the data source 286 * from a JNDI service provider. 287 * 288 * @return value of dataSourceName. 289 */ 290 public String getDataSourceName() { 291 return dataSourceName; 292 } 293 294 /** 295 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per user pool. 296 * 297 * @return The default value for {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per user 298 * pool. 299 */ 300 public boolean getDefaultBlockWhenExhausted() { 301 return this.defaultBlockWhenExhausted; 302 } 303 304 /** 305 * Gets the default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for each per user pool. 306 * 307 * @return The default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for each per user pool. 308 * @since 2.10.0 309 */ 310 public Duration getDefaultDurationBetweenEvictionRuns() { 311 return this.defaultDurationBetweenEvictionRuns; 312 } 313 314 /** 315 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for each per user 316 * pool. 317 * 318 * @return The default value for {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for each per user 319 * pool. 320 */ 321 public String getDefaultEvictionPolicyClassName() { 322 return this.defaultEvictionPolicyClassName; 323 } 324 325 /** 326 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool. 327 * 328 * @return The default value for {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool. 329 */ 330 public boolean getDefaultLifo() { 331 return this.defaultLifo; 332 } 333 334 /** 335 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user pool. 336 * 337 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user pool. 338 */ 339 public int getDefaultMaxIdle() { 340 return this.defaultMaxIdle; 341 } 342 343 /** 344 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per user pool. 345 * 346 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per user pool. 347 */ 348 public int getDefaultMaxTotal() { 349 return this.defaultMaxTotal; 350 } 351 352 /** 353 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 354 * 355 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 356 * @since 2.9.0 357 */ 358 public Duration getDefaultMaxWait() { 359 return this.defaultMaxWaitDuration; 360 } 361 362 /** 363 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 364 * 365 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 366 * @deprecated Use {@link #getDefaultMaxWait()}. 367 */ 368 @Deprecated 369 public long getDefaultMaxWaitMillis() { 370 return getDefaultMaxWait().toMillis(); 371 } 372 373 /** 374 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per user 375 * pool. 376 * 377 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per 378 * user pool. 379 * @since 2.10.0 380 */ 381 public Duration getDefaultMinEvictableIdleDuration() { 382 return this.defaultMinEvictableIdleDuration; 383 } 384 385 /** 386 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per user 387 * pool. 388 * 389 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per 390 * user pool. 391 * @deprecated Use {@link #getDefaultMinEvictableIdleDuration()}. 392 */ 393 @Deprecated 394 public long getDefaultMinEvictableIdleTimeMillis() { 395 return this.defaultMinEvictableIdleDuration.toMillis(); 396 } 397 398 /** 399 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user pool. 400 * 401 * @return The default value for {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user pool. 402 */ 403 public int getDefaultMinIdle() { 404 return this.defaultMinIdle; 405 } 406 407 /** 408 * Gets the default value for {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each per user 409 * pool. 410 * 411 * @return The default value for {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each per user 412 * pool. 413 */ 414 public int getDefaultNumTestsPerEvictionRun() { 415 return this.defaultNumTestsPerEvictionRun; 416 } 417 418 /** 419 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 420 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 421 * 422 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 423 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 424 * @since 2.10.0 425 */ 426 public Duration getDefaultSoftMinEvictableIdleDuration() { 427 return this.defaultSoftMinEvictableIdleDuration; 428 } 429 430 /** 431 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 432 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 433 * 434 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 435 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 436 * @deprecated Use {@link #getDefaultSoftMinEvictableIdleDuration()}. 437 */ 438 @Deprecated 439 public long getDefaultSoftMinEvictableIdleTimeMillis() { 440 return this.defaultSoftMinEvictableIdleDuration.toMillis(); 441 } 442 443 /** 444 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 445 * GenericObjectPool#getTestOnBorrow()} for each per user pool. 446 * 447 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 448 * GenericObjectPool#getTestOnBorrow()} for each per user pool. 449 */ 450 public boolean getDefaultTestOnBorrow() { 451 return this.defaultTestOnBorrow; 452 } 453 454 /** 455 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 456 * GenericObjectPool#getTestOnCreate()} for each per user pool. 457 * 458 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 459 * GenericObjectPool#getTestOnCreate()} for each per user pool. 460 */ 461 public boolean getDefaultTestOnCreate() { 462 return this.defaultTestOnCreate; 463 } 464 465 /** 466 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 467 * GenericObjectPool#getTestOnReturn()} for each per user pool. 468 * 469 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 470 * GenericObjectPool#getTestOnReturn()} for each per user pool. 471 */ 472 public boolean getDefaultTestOnReturn() { 473 return this.defaultTestOnReturn; 474 } 475 476 /** 477 * Gets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 478 * GenericObjectPool#getTestWhileIdle()} for each per user pool. 479 * 480 * @return The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 481 * GenericObjectPool#getTestWhileIdle()} for each per user pool. 482 */ 483 public boolean getDefaultTestWhileIdle() { 484 return this.defaultTestWhileIdle; 485 } 486 487 /** 488 * Gets the default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns ()} for each per user pool. 489 * 490 * @return The default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns ()} for each per user pool. 491 * @deprecated Use {@link #getDefaultDurationBetweenEvictionRuns()}. 492 */ 493 @Deprecated 494 public long getDefaultTimeBetweenEvictionRunsMillis() { 495 return this.defaultDurationBetweenEvictionRuns.toMillis(); 496 } 497 498 /** 499 * Gets the value of defaultTransactionIsolation, which defines the state of connections handed out from this pool. 500 * The value can be changed on the Connection using Connection.setTransactionIsolation(int). If this method returns 501 * -1, the default is JDBC driver dependent. 502 * 503 * @return value of defaultTransactionIsolation. 504 */ 505 public int getDefaultTransactionIsolation() { 506 return defaultTransactionIsolation; 507 } 508 509 /** 510 * Gets the description. This property is defined by JDBC as for use with GUI (or other) tools that might deploy the 511 * datasource. It serves no internal purpose. 512 * 513 * @return value of description. 514 */ 515 public String getDescription() { 516 return description; 517 } 518 519 /** 520 * Gets the instance key. 521 * 522 * @return the instance key. 523 */ 524 protected String getInstanceKey() { 525 return instanceKey; 526 } 527 528 /** 529 * Gets the value of jndiEnvironment which is used when instantiating a JNDI InitialContext. This InitialContext is 530 * used to locate the back end ConnectionPoolDataSource. 531 * 532 * @param key 533 * JNDI environment key. 534 * @return value of jndiEnvironment. 535 */ 536 public String getJndiEnvironment(final String key) { 537 String value = null; 538 if (jndiEnvironment != null) { 539 value = jndiEnvironment.getProperty(key); 540 } 541 return value; 542 } 543 544 /** 545 * Gets the value of loginTimeout. 546 * 547 * @return value of loginTimeout. 548 * @deprecated Use {@link #getLoginTimeoutDuration()}. 549 */ 550 @Deprecated 551 @Override 552 public int getLoginTimeout() { 553 return (int) loginTimeoutDuration.getSeconds(); 554 } 555 556 /** 557 * Gets the value of loginTimeout. 558 * 559 * @return value of loginTimeout. 560 * @since 2.10.0 561 */ 562 public Duration getLoginTimeoutDuration() { 563 return loginTimeoutDuration; 564 } 565 566 /** 567 * Gets the value of logWriter. 568 * 569 * @return value of logWriter. 570 */ 571 @Override 572 public PrintWriter getLogWriter() { 573 if (logWriter == null) { 574 logWriter = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8)); 575 } 576 return logWriter; 577 } 578 579 /** 580 * Gets the maximum permitted lifetime of a connection. A value of zero or less indicates an 581 * infinite lifetime. 582 * 583 * @return The maximum permitted lifetime of a connection. A value of zero or less indicates an 584 * infinite lifetime. 585 * @since 2.10.0 586 */ 587 public Duration getMaxConnDuration() { 588 return maxConnDuration; 589 } 590 591 /** 592 * Gets the maximum permitted lifetime of a connection. A value of zero or less indicates an 593 * infinite lifetime. 594 * 595 * @return The maximum permitted lifetime of a connection. A value of zero or less indicates an 596 * infinite lifetime. 597 * @deprecated Use {@link #getMaxConnDuration()}. 598 */ 599 @Deprecated 600 public Duration getMaxConnLifetime() { 601 return maxConnDuration; 602 } 603 604 /** 605 * Gets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 606 * infinite lifetime. 607 * 608 * @return The maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 609 * infinite lifetime. 610 * @deprecated Use {@link #getMaxConnLifetime()}. 611 */ 612 @Deprecated 613 public long getMaxConnLifetimeMillis() { 614 return maxConnDuration.toMillis(); 615 } 616 617 @Override 618 public Logger getParentLogger() throws SQLFeatureNotSupportedException { 619 throw new SQLFeatureNotSupportedException(); 620 } 621 622 /** 623 * This method is protected but can only be implemented in this package because PooledConnectionAndInfo is a package 624 * private type. 625 * 626 * @param userName The user name. 627 * @param userPassword The user password. 628 * @return Matching PooledConnectionAndInfo. 629 * @throws SQLException Connection or registration failure. 630 */ 631 protected abstract PooledConnectionAndInfo getPooledConnectionAndInfo(String userName, String userPassword) 632 throws SQLException; 633 634 /** 635 * Gets the SQL query that will be used to validate connections from this pool before returning them to the caller. 636 * If specified, this query <strong>MUST</strong> be an SQL SELECT statement that returns at least one row. If not 637 * specified, {@link Connection#isValid(int)} will be used to validate connections. 638 * 639 * @return The SQL query that will be used to validate connections from this pool before returning them to the 640 * caller. 641 */ 642 public String getValidationQuery() { 643 return this.validationQuery; 644 } 645 646 /** 647 * Returns the timeout in seconds before the validation query fails. 648 * 649 * @return The timeout in seconds before the validation query fails. 650 * @deprecated Use {@link #getValidationQueryTimeoutDuration()}. 651 */ 652 @Deprecated 653 public int getValidationQueryTimeout() { 654 return (int) validationQueryTimeoutDuration.getSeconds(); 655 } 656 657 /** 658 * Returns the timeout Duration before the validation query fails. 659 * 660 * @return The timeout Duration before the validation query fails. 661 */ 662 public Duration getValidationQueryTimeoutDuration() { 663 return validationQueryTimeoutDuration; 664 } 665 666 /** 667 * Gets the value of defaultAutoCommit, which defines the state of connections handed out from this pool. The value 668 * can be changed on the Connection using Connection.setAutoCommit(boolean). The default is {@code null} which 669 * will use the default value for the drive. 670 * 671 * @return value of defaultAutoCommit. 672 */ 673 public Boolean isDefaultAutoCommit() { 674 return defaultAutoCommit; 675 } 676 677 /** 678 * Gets the value of defaultReadOnly, which defines the state of connections handed out from this pool. The value 679 * can be changed on the Connection using Connection.setReadOnly(boolean). The default is {@code null} which 680 * will use the default value for the drive. 681 * 682 * @return value of defaultReadOnly. 683 */ 684 public Boolean isDefaultReadOnly() { 685 return defaultReadOnly; 686 } 687 688 /** 689 * Whether a rollback will be issued after executing the SQL query that will be used to validate connections from 690 * this pool before returning them to the caller. 691 * 692 * @return true if a rollback will be issued after executing the validation query 693 */ 694 public boolean isRollbackAfterValidation() { 695 return this.rollbackAfterValidation; 696 } 697 698 @Override 699 public boolean isWrapperFor(final Class<?> iface) throws SQLException { 700 return iface.isInstance(this); 701 } 702 703 /** 704 * Sets the back end ConnectionPoolDataSource. This property should not be set if using JNDI to access the 705 * data source. 706 * 707 * @param dataSource 708 * Value to assign to connectionPoolDataSource. 709 */ 710 public void setConnectionPoolDataSource(final ConnectionPoolDataSource dataSource) { 711 assertInitializationAllowed(); 712 if (dataSourceName != null) { 713 throw new IllegalStateException("Cannot set the DataSource, if JNDI is used."); 714 } 715 if (this.dataSource != null) { 716 throw new IllegalStateException("The CPDS has already been set. It cannot be altered."); 717 } 718 this.dataSource = dataSource; 719 instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this); 720 } 721 722 /** 723 * Sets the name of the ConnectionPoolDataSource which backs this pool. This name is used to look up the data source 724 * from a JNDI service provider. 725 * 726 * @param dataSourceName 727 * Value to assign to dataSourceName. 728 */ 729 public void setDataSourceName(final String dataSourceName) { 730 assertInitializationAllowed(); 731 if (dataSource != null) { 732 throw new IllegalStateException("Cannot set the JNDI name for the DataSource, if already " 733 + "set using setConnectionPoolDataSource."); 734 } 735 if (this.dataSourceName != null) { 736 throw new IllegalStateException("The DataSourceName has already been set. " + "It cannot be altered."); 737 } 738 this.dataSourceName = dataSourceName; 739 instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this); 740 } 741 742 /** 743 * Sets the value of defaultAutoCommit, which defines the state of connections handed out from this pool. The value 744 * can be changed on the Connection using Connection.setAutoCommit(boolean). The default is {@code null} which 745 * will use the default value for the drive. 746 * 747 * @param defaultAutoCommit 748 * Value to assign to defaultAutoCommit. 749 */ 750 public void setDefaultAutoCommit(final Boolean defaultAutoCommit) { 751 assertInitializationAllowed(); 752 this.defaultAutoCommit = defaultAutoCommit; 753 } 754 755 /** 756 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per user pool. 757 * 758 * @param blockWhenExhausted 759 * The default value for {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per user 760 * pool. 761 */ 762 public void setDefaultBlockWhenExhausted(final boolean blockWhenExhausted) { 763 assertInitializationAllowed(); 764 this.defaultBlockWhenExhausted = blockWhenExhausted; 765 } 766 767 /** 768 * Sets the default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns ()} for each per user pool. 769 * 770 * @param defaultDurationBetweenEvictionRuns The default value for 771 * {@link GenericObjectPool#getDurationBetweenEvictionRuns ()} for each per user pool. 772 * @since 2.10.0 773 */ 774 public void setDefaultDurationBetweenEvictionRuns(final Duration defaultDurationBetweenEvictionRuns) { 775 assertInitializationAllowed(); 776 this.defaultDurationBetweenEvictionRuns = defaultDurationBetweenEvictionRuns; 777 } 778 779 /** 780 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for each per user 781 * pool. 782 * 783 * @param evictionPolicyClassName 784 * The default value for {@link GenericKeyedObjectPoolConfig#getEvictionPolicyClassName()} for each per 785 * user pool. 786 */ 787 public void setDefaultEvictionPolicyClassName(final String evictionPolicyClassName) { 788 assertInitializationAllowed(); 789 this.defaultEvictionPolicyClassName = evictionPolicyClassName; 790 } 791 792 /** 793 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool. 794 * 795 * @param lifo 796 * The default value for {@link GenericKeyedObjectPoolConfig#getLifo()} for each per user pool. 797 */ 798 public void setDefaultLifo(final boolean lifo) { 799 assertInitializationAllowed(); 800 this.defaultLifo = lifo; 801 } 802 803 /** 804 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user pool. 805 * 806 * @param maxIdle 807 * The default value for {@link GenericKeyedObjectPoolConfig#getMaxIdlePerKey()} for each per user pool. 808 */ 809 public void setDefaultMaxIdle(final int maxIdle) { 810 assertInitializationAllowed(); 811 this.defaultMaxIdle = maxIdle; 812 } 813 814 /** 815 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per user pool. 816 * 817 * @param maxTotal 818 * The default value for {@link GenericKeyedObjectPoolConfig#getMaxTotalPerKey()} for each per user pool. 819 */ 820 public void setDefaultMaxTotal(final int maxTotal) { 821 assertInitializationAllowed(); 822 this.defaultMaxTotal = maxTotal; 823 } 824 825 /** 826 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 827 * 828 * @param maxWaitMillis 829 * The default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitDuration()} for each per user pool. 830 * @since 2.9.0 831 */ 832 public void setDefaultMaxWait(final Duration maxWaitMillis) { 833 assertInitializationAllowed(); 834 this.defaultMaxWaitDuration = maxWaitMillis; 835 } 836 837 /** 838 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitMillis()} for each per user pool. 839 * 840 * @param maxWaitMillis 841 * The default value for {@link GenericKeyedObjectPoolConfig#getMaxWaitMillis()} for each per user pool. 842 * @deprecated Use {@link #setDefaultMaxWait(Duration)}. 843 */ 844 @Deprecated 845 public void setDefaultMaxWaitMillis(final long maxWaitMillis) { 846 setDefaultMaxWait(Duration.ofMillis(maxWaitMillis)); 847 } 848 849 /** 850 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per user 851 * pool. 852 * 853 * @param defaultMinEvictableIdleDuration 854 * The default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each 855 * per user pool. 856 * @since 2.10.0 857 */ 858 public void setDefaultMinEvictableIdle(final Duration defaultMinEvictableIdleDuration) { 859 assertInitializationAllowed(); 860 this.defaultMinEvictableIdleDuration = defaultMinEvictableIdleDuration; 861 } 862 863 /** 864 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each per user 865 * pool. 866 * 867 * @param minEvictableIdleTimeMillis 868 * The default value for {@link GenericKeyedObjectPoolConfig#getMinEvictableIdleDuration()} for each 869 * per user pool. 870 * @deprecated Use {@link #setDefaultMinEvictableIdle(Duration)}. 871 */ 872 @Deprecated 873 public void setDefaultMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) { 874 assertInitializationAllowed(); 875 this.defaultMinEvictableIdleDuration = Duration.ofMillis(minEvictableIdleTimeMillis); 876 } 877 878 /** 879 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user pool. 880 * 881 * @param minIdle 882 * The default value for {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} for each per user pool. 883 */ 884 public void setDefaultMinIdle(final int minIdle) { 885 assertInitializationAllowed(); 886 this.defaultMinIdle = minIdle; 887 } 888 889 /** 890 * Sets the default value for {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each per user 891 * pool. 892 * 893 * @param numTestsPerEvictionRun 894 * The default value for {@link GenericKeyedObjectPoolConfig#getNumTestsPerEvictionRun()} for each per 895 * user pool. 896 */ 897 public void setDefaultNumTestsPerEvictionRun(final int numTestsPerEvictionRun) { 898 assertInitializationAllowed(); 899 this.defaultNumTestsPerEvictionRun = numTestsPerEvictionRun; 900 } 901 902 /** 903 * Sets the value of defaultReadOnly, which defines the state of connections handed out from this pool. The value 904 * can be changed on the Connection using Connection.setReadOnly(boolean). The default is {@code null} which 905 * will use the default value for the drive. 906 * 907 * @param defaultReadOnly 908 * Value to assign to defaultReadOnly. 909 */ 910 public void setDefaultReadOnly(final Boolean defaultReadOnly) { 911 assertInitializationAllowed(); 912 this.defaultReadOnly = defaultReadOnly; 913 } 914 915 /** 916 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 917 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 918 * 919 * @param defaultSoftMinEvictableIdleDuration 920 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 921 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 922 * @since 2.10.0 923 */ 924 public void setDefaultSoftMinEvictableIdle(final Duration defaultSoftMinEvictableIdleDuration) { 925 assertInitializationAllowed(); 926 this.defaultSoftMinEvictableIdleDuration = defaultSoftMinEvictableIdleDuration; 927 } 928 929 /** 930 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 931 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 932 * 933 * @param softMinEvictableIdleTimeMillis 934 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 935 * GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} for each per user pool. 936 * @deprecated Use {@link #setDefaultSoftMinEvictableIdle(Duration)}. 937 */ 938 @Deprecated 939 public void setDefaultSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) { 940 assertInitializationAllowed(); 941 this.defaultSoftMinEvictableIdleDuration = Duration.ofMillis(softMinEvictableIdleTimeMillis); 942 } 943 944 /** 945 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 946 * GenericObjectPool#getTestOnBorrow()} for each per user pool. 947 * 948 * @param testOnBorrow 949 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 950 * GenericObjectPool#getTestOnBorrow()} for each per user pool. 951 */ 952 public void setDefaultTestOnBorrow(final boolean testOnBorrow) { 953 assertInitializationAllowed(); 954 this.defaultTestOnBorrow = testOnBorrow; 955 } 956 957 /** 958 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 959 * GenericObjectPool#getTestOnCreate()} for each per user pool. 960 * 961 * @param testOnCreate 962 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 963 * GenericObjectPool#getTestOnCreate()} for each per user pool. 964 */ 965 public void setDefaultTestOnCreate(final boolean testOnCreate) { 966 assertInitializationAllowed(); 967 this.defaultTestOnCreate = testOnCreate; 968 } 969 970 /** 971 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 972 * GenericObjectPool#getTestOnReturn()} for each per user pool. 973 * 974 * @param testOnReturn 975 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 976 * GenericObjectPool#getTestOnReturn()} for each per user pool. 977 */ 978 public void setDefaultTestOnReturn(final boolean testOnReturn) { 979 assertInitializationAllowed(); 980 this.defaultTestOnReturn = testOnReturn; 981 } 982 983 /** 984 * Sets the default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 985 * GenericObjectPool#getTestWhileIdle()} for each per user pool. 986 * 987 * @param testWhileIdle 988 * The default value for {@link org.apache.commons.pool2.impl.GenericObjectPool 989 * GenericObjectPool#getTestWhileIdle()} for each per user pool. 990 */ 991 public void setDefaultTestWhileIdle(final boolean testWhileIdle) { 992 assertInitializationAllowed(); 993 this.defaultTestWhileIdle = testWhileIdle; 994 } 995 996 /** 997 * Sets the default value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for each per user pool. 998 * 999 * @param timeBetweenEvictionRunsMillis The default value for 1000 * {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for each per user pool. 1001 * @deprecated Use {@link #setDefaultDurationBetweenEvictionRuns(Duration)}. 1002 */ 1003 @Deprecated 1004 public void setDefaultTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) { 1005 assertInitializationAllowed(); 1006 this.defaultDurationBetweenEvictionRuns = Duration.ofMillis(timeBetweenEvictionRunsMillis); 1007 } 1008 1009 /** 1010 * Sets the value of defaultTransactionIsolation, which defines the state of connections handed out from this pool. 1011 * The value can be changed on the Connection using Connection.setTransactionIsolation(int). The default is JDBC 1012 * driver dependent. 1013 * 1014 * @param defaultTransactionIsolation 1015 * Value to assign to defaultTransactionIsolation 1016 */ 1017 public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) { 1018 assertInitializationAllowed(); 1019 switch (defaultTransactionIsolation) { 1020 case Connection.TRANSACTION_NONE: 1021 case Connection.TRANSACTION_READ_COMMITTED: 1022 case Connection.TRANSACTION_READ_UNCOMMITTED: 1023 case Connection.TRANSACTION_REPEATABLE_READ: 1024 case Connection.TRANSACTION_SERIALIZABLE: 1025 break; 1026 default: 1027 throw new IllegalArgumentException(BAD_TRANSACTION_ISOLATION); 1028 } 1029 this.defaultTransactionIsolation = defaultTransactionIsolation; 1030 } 1031 1032 /** 1033 * Sets the description. This property is defined by JDBC as for use with GUI (or other) tools that might deploy the 1034 * datasource. It serves no internal purpose. 1035 * 1036 * @param description 1037 * Value to assign to description. 1038 */ 1039 public void setDescription(final String description) { 1040 this.description = description; 1041 } 1042 1043 /** 1044 * Sets the JNDI environment to be used when instantiating a JNDI InitialContext. This InitialContext is used to 1045 * locate the back end ConnectionPoolDataSource. 1046 * 1047 * @param properties 1048 * the JNDI environment property to set which will overwrite any current settings 1049 */ 1050 void setJndiEnvironment(final Properties properties) { 1051 if (jndiEnvironment == null) { 1052 jndiEnvironment = new Properties(); 1053 } else { 1054 jndiEnvironment.clear(); 1055 } 1056 jndiEnvironment.putAll(properties); 1057 } 1058 1059 /** 1060 * Sets the value of the given JNDI environment property to be used when instantiating a JNDI InitialContext. This 1061 * InitialContext is used to locate the back end ConnectionPoolDataSource. 1062 * 1063 * @param key 1064 * the JNDI environment property to set. 1065 * @param value 1066 * the value assigned to specified JNDI environment property. 1067 */ 1068 public void setJndiEnvironment(final String key, final String value) { 1069 if (jndiEnvironment == null) { 1070 jndiEnvironment = new Properties(); 1071 } 1072 jndiEnvironment.setProperty(key, value); 1073 } 1074 1075 /** 1076 * Sets the value of loginTimeout. 1077 * 1078 * @param loginTimeout 1079 * Value to assign to loginTimeout. 1080 * @since 2.10.0 1081 */ 1082 public void setLoginTimeout(final Duration loginTimeout) { 1083 this.loginTimeoutDuration = loginTimeout; 1084 } 1085 1086 /** 1087 * Sets the value of loginTimeout. 1088 * 1089 * @param loginTimeout 1090 * Value to assign to loginTimeout. 1091 * @deprecated Use {@link #setLoginTimeout(Duration)}. 1092 */ 1093 @Deprecated 1094 @Override 1095 public void setLoginTimeout(final int loginTimeout) { 1096 this.loginTimeoutDuration = Duration.ofSeconds(loginTimeout); 1097 } 1098 1099 /** 1100 * Sets the value of logWriter. 1101 * 1102 * @param logWriter 1103 * Value to assign to logWriter. 1104 */ 1105 @Override 1106 public void setLogWriter(final PrintWriter logWriter) { 1107 this.logWriter = logWriter; 1108 } 1109 1110 /** 1111 * <p> 1112 * Sets the maximum permitted lifetime of a connection. A value of zero or less indicates an 1113 * infinite lifetime. 1114 * </p> 1115 * <p> 1116 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1117 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1118 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1119 * </p> 1120 * 1121 * @param maxConnLifetimeMillis 1122 * The maximum permitted lifetime of a connection. A value of zero or less indicates an 1123 * infinite lifetime. 1124 * @since 2.9.0 1125 */ 1126 public void setMaxConnLifetime(final Duration maxConnLifetimeMillis) { 1127 this.maxConnDuration = maxConnLifetimeMillis; 1128 } 1129 1130 /** 1131 * <p> 1132 * Sets the maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 1133 * infinite lifetime. 1134 * </p> 1135 * <p> 1136 * Note: this method currently has no effect once the pool has been initialized. The pool is initialized the first 1137 * time one of the following methods is invoked: <code>getConnection, setLogwriter, 1138 * setLoginTimeout, getLoginTimeout, getLogWriter.</code> 1139 * </p> 1140 * 1141 * @param maxConnLifetimeMillis 1142 * The maximum permitted lifetime of a connection in milliseconds. A value of zero or less indicates an 1143 * infinite lifetime. 1144 * @deprecated Use {@link #setMaxConnLifetime(Duration)}. 1145 */ 1146 @Deprecated 1147 public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) { 1148 setMaxConnLifetime(Duration.ofMillis(maxConnLifetimeMillis)); 1149 } 1150 1151 /** 1152 * Whether a rollback will be issued after executing the SQL query that will be used to validate connections from 1153 * this pool before returning them to the caller. Default behavior is NOT to issue a rollback. The setting will only 1154 * have an effect if a validation query is set 1155 * 1156 * @param rollbackAfterValidation 1157 * new property value 1158 */ 1159 public void setRollbackAfterValidation(final boolean rollbackAfterValidation) { 1160 assertInitializationAllowed(); 1161 this.rollbackAfterValidation = rollbackAfterValidation; 1162 } 1163 1164 protected abstract void setupDefaults(Connection connection, String userName) throws SQLException; 1165 1166 /** 1167 * Sets the SQL query that will be used to validate connections from this pool before returning them to the caller. 1168 * If specified, this query <strong>MUST</strong> be an SQL SELECT statement that returns at least one row. If not 1169 * specified, connections will be validated using {@link Connection#isValid(int)}. 1170 * 1171 * @param validationQuery 1172 * The SQL query that will be used to validate connections from this pool before returning them to the 1173 * caller. 1174 */ 1175 public void setValidationQuery(final String validationQuery) { 1176 assertInitializationAllowed(); 1177 this.validationQuery = validationQuery; 1178 } 1179 1180 /** 1181 * Sets the timeout duration before the validation query fails. 1182 * 1183 * @param validationQueryTimeoutDuration 1184 * The new timeout duration. 1185 */ 1186 public void setValidationQueryTimeout(final Duration validationQueryTimeoutDuration) { 1187 this.validationQueryTimeoutDuration = validationQueryTimeoutDuration; 1188 } 1189 1190 /** 1191 * Sets the timeout in seconds before the validation query fails. 1192 * 1193 * @param validationQueryTimeoutSeconds 1194 * The new timeout in seconds 1195 * @deprecated Use {@link #setValidationQueryTimeout(Duration)}. 1196 */ 1197 @Deprecated 1198 public void setValidationQueryTimeout(final int validationQueryTimeoutSeconds) { 1199 this.validationQueryTimeoutDuration = Duration.ofSeconds(validationQueryTimeoutSeconds); 1200 } 1201 1202 protected ConnectionPoolDataSource testCPDS(final String userName, final String userPassword) 1203 throws javax.naming.NamingException, SQLException { 1204 // The source of physical db connections 1205 ConnectionPoolDataSource cpds = this.dataSource; 1206 if (cpds == null) { 1207 Context ctx = null; 1208 if (jndiEnvironment == null) { 1209 ctx = new InitialContext(); 1210 } else { 1211 ctx = new InitialContext(jndiEnvironment); 1212 } 1213 final Object ds = ctx.lookup(dataSourceName); 1214 if (!(ds instanceof ConnectionPoolDataSource)) { 1215 throw new SQLException("Illegal configuration: " + "DataSource " + dataSourceName + " (" 1216 + ds.getClass().getName() + ")" + " doesn't implement javax.sql.ConnectionPoolDataSource"); 1217 } 1218 cpds = (ConnectionPoolDataSource) ds; 1219 } 1220 1221 // try to get a connection with the supplied userName/password 1222 PooledConnection conn = null; 1223 try { 1224 if (userName != null) { 1225 conn = cpds.getPooledConnection(userName, userPassword); 1226 } else { 1227 conn = cpds.getPooledConnection(); 1228 } 1229 if (conn == null) { 1230 throw new SQLException("Cannot connect using the supplied userName/password"); 1231 } 1232 } finally { 1233 if (conn != null) { 1234 try { 1235 conn.close(); 1236 } catch (final SQLException ignored) { 1237 // at least we could connect 1238 } 1239 } 1240 } 1241 return cpds; 1242 } 1243 1244 /** 1245 * @since 2.6.0 1246 */ 1247 @Override 1248 public synchronized String toString() { 1249 final StringBuilder builder = new StringBuilder(super.toString()); 1250 builder.append('['); 1251 toStringFields(builder); 1252 builder.append(']'); 1253 return builder.toString(); 1254 } 1255 1256 protected void toStringFields(final StringBuilder builder) { 1257 builder.append("getConnectionCalled="); 1258 builder.append(getConnectionCalled); 1259 builder.append(", dataSource="); 1260 builder.append(dataSource); 1261 builder.append(", dataSourceName="); 1262 builder.append(dataSourceName); 1263 builder.append(", description="); 1264 builder.append(description); 1265 builder.append(", jndiEnvironment="); 1266 builder.append(jndiEnvironment); 1267 builder.append(", loginTimeoutDuration="); 1268 builder.append(loginTimeoutDuration); 1269 builder.append(", logWriter="); 1270 builder.append(logWriter); 1271 builder.append(", instanceKey="); 1272 builder.append(instanceKey); 1273 builder.append(", defaultBlockWhenExhausted="); 1274 builder.append(defaultBlockWhenExhausted); 1275 builder.append(", defaultEvictionPolicyClassName="); 1276 builder.append(defaultEvictionPolicyClassName); 1277 builder.append(", defaultLifo="); 1278 builder.append(defaultLifo); 1279 builder.append(", defaultMaxIdle="); 1280 builder.append(defaultMaxIdle); 1281 builder.append(", defaultMaxTotal="); 1282 builder.append(defaultMaxTotal); 1283 builder.append(", defaultMaxWaitDuration="); 1284 builder.append(defaultMaxWaitDuration); 1285 builder.append(", defaultMinEvictableIdleDuration="); 1286 builder.append(defaultMinEvictableIdleDuration); 1287 builder.append(", defaultMinIdle="); 1288 builder.append(defaultMinIdle); 1289 builder.append(", defaultNumTestsPerEvictionRun="); 1290 builder.append(defaultNumTestsPerEvictionRun); 1291 builder.append(", defaultSoftMinEvictableIdleDuration="); 1292 builder.append(defaultSoftMinEvictableIdleDuration); 1293 builder.append(", defaultTestOnCreate="); 1294 builder.append(defaultTestOnCreate); 1295 builder.append(", defaultTestOnBorrow="); 1296 builder.append(defaultTestOnBorrow); 1297 builder.append(", defaultTestOnReturn="); 1298 builder.append(defaultTestOnReturn); 1299 builder.append(", defaultTestWhileIdle="); 1300 builder.append(defaultTestWhileIdle); 1301 builder.append(", defaultDurationBetweenEvictionRuns="); 1302 builder.append(defaultDurationBetweenEvictionRuns); 1303 builder.append(", validationQuery="); 1304 builder.append(validationQuery); 1305 builder.append(", validationQueryTimeoutDuration="); 1306 builder.append(validationQueryTimeoutDuration); 1307 builder.append(", rollbackAfterValidation="); 1308 builder.append(rollbackAfterValidation); 1309 builder.append(", maxConnDuration="); 1310 builder.append(maxConnDuration); 1311 builder.append(", defaultAutoCommit="); 1312 builder.append(defaultAutoCommit); 1313 builder.append(", defaultTransactionIsolation="); 1314 builder.append(defaultTransactionIsolation); 1315 builder.append(", defaultReadOnly="); 1316 builder.append(defaultReadOnly); 1317 } 1318 1319 @Override 1320 @SuppressWarnings("unchecked") 1321 public <T> T unwrap(final Class<T> iface) throws SQLException { 1322 if (isWrapperFor(iface)) { 1323 return (T) this; 1324 } 1325 throw new SQLException(this + " is not a wrapper for " + iface); 1326 } 1327}