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