in src/main/java/org/apache/commons/dbcp2/datasources/InstanceKeyDataSource.java [236:308]
public Connection getConnection(final String userName, final String userPassword) throws SQLException {
if (instanceKey == null) {
throw new SQLException("Must set the ConnectionPoolDataSource "
+ "through setDataSourceName or setConnectionPoolDataSource" + " before calling getConnection.");
}
getConnectionCalled = true;
PooledConnectionAndInfo info = null;
try {
info = getPooledConnectionAndInfo(userName, userPassword);
} catch (final RuntimeException | SQLException e) {
closeDueToException(info);
throw e;
} catch (final Exception e) {
closeDueToException(info);
throw new SQLException("Cannot borrow connection from pool", e);
}
// Password on PooledConnectionAndInfo does not match
if (!(null == userPassword ? null == info.getPassword() : userPassword.equals(info.getPassword()))) {
try { // See if password has changed by attempting connection
testCPDS(userName, userPassword);
} catch (final SQLException ex) {
// Password has not changed, so refuse client, but return connection to the pool
closeDueToException(info);
throw new SQLException(
"Given password did not match password used" + " to create the PooledConnection.", ex);
} catch (final javax.naming.NamingException ne) {
throw new SQLException("NamingException encountered connecting to database", ne);
}
/*
* Password must have changed -> destroy connection and keep retrying until we get a new, good one,
* destroying any idle connections with the old password as we pull them from the pool.
*/
final UserPassKey upkey = info.getUserPassKey();
final PooledConnectionManager manager = getConnectionManager(upkey);
// Destroy and remove from pool
manager.invalidate(info.getPooledConnection());
// Reset the password on the factory if using CPDSConnectionFactory
manager.setPassword(upkey.getPassword());
info = null;
for (int i = 0; i < 10; i++) { // Bound the number of retries - only needed if bad instances return
try {
info = getPooledConnectionAndInfo(userName, userPassword);
} catch (final RuntimeException | SQLException e) {
closeDueToException(info);
throw e;
} catch (final Exception e) {
closeDueToException(info);
throw new SQLException("Cannot borrow connection from pool", e);
}
if (info != null && userPassword != null && userPassword.equals(info.getPassword())) {
break;
}
if (info != null) {
manager.invalidate(info.getPooledConnection());
}
info = null;
}
if (info == null) {
throw new SQLException("Cannot borrow connection from pool - password change failure.");
}
}
final Connection connection = info.getPooledConnection().getConnection();
try {
setupDefaults(connection, userName);
connection.clearWarnings();
return connection;
} catch (final SQLException ex) {
Utils.close(connection, e -> getLogWriter().println("ignoring exception during close: " + e));
throw ex;
}
}