/** * This will be called if the Connection returned by the getConnection method came from a * PooledConnection, and the user calls the close() method of this connection object. What we need * to do here is to release this PooledConnection from our pool... */ @Override public void connectionClosed(ConnectionEvent event) { PooledConnection pc = (PooledConnection) event.getSource(); // if this event occurred because we were validating, or if this // connection has been marked for removal, ignore it // otherwise return the connection to the pool. if (!validatingSet.contains(pc)) { PooledConnectionAndInfo pci = pcMap.get(pc); if (pci == null) { throw new IllegalStateException(NO_KEY_MESSAGE); } try { _pool.returnObject(pci.getUserPassKey(), pci); } catch (Exception e) { System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + "NOT BE RETURNED TO THE POOL"); pc.removeConnectionEventListener(this); try { _pool.invalidateObject(pci.getUserPassKey(), pci); } catch (Exception e3) { System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + pci); e3.printStackTrace(); } } } }
/** * This will be called if the Connection returned by the getConnection method came from a * PooledConnection, and the user calls the close() method of this connection object. What we need * to do here is to release this PooledConnection from our pool... */ public void connectionClosed(ConnectionEvent event) { PooledConnection pc = (PooledConnection) event.getSource(); // if this event occurred because we were validating, or if this // connection has been marked for removal, ignore it // otherwise return the connection to the pool. if (!muteMap.containsKey(pc)) { PooledConnectionAndInfo info = (PooledConnectionAndInfo) pcMap.get(pc); if (info == null) { throw new IllegalStateException(NO_KEY_MESSAGE); } try { _pool.returnObject(info.getUserPassKey(), info); } catch (Exception e) { System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + "NOT BE RETURNED TO THE POOL"); cleanupMap.put(pc, null); // mark for cleanup muteMap.put(pc, null); // ignore events until listener is removed try { _pool.invalidateObject(info.getUserPassKey(), info); } catch (Exception e3) { System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info); e3.printStackTrace(); } } } }
/** * If a fatal error occurs, close the underlying physical connection so as not to be returned in * the future */ public void connectionErrorOccurred(ConnectionEvent event) { PooledConnection pc = (PooledConnection) event.getSource(); if (cleanupMap.containsKey(pc)) { return; // waiting for listener cleanup - ignore event } try { if (null != event.getSQLException()) { System.err.println( "CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR (" + event.getSQLException() + ")"); } cleanupMap.put(pc, null); // mark for cleanup muteMap.put(pc, null); // ignore events until listener is removed } catch (Exception ignore) { // ignore } PooledConnectionAndInfo info = (PooledConnectionAndInfo) pcMap.get(pc); if (info == null) { throw new IllegalStateException(NO_KEY_MESSAGE); } try { _pool.invalidateObject(info.getUserPassKey(), info); } catch (Exception e) { System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info); e.printStackTrace(); } }
/** * Invalidates the PooledConnection in the pool. The KeyedCPDSConnectionFactory closes the * connection and pool counters are updated appropriately. Also clears any idle instances * associated with the username that was used to create the PooledConnection. Connections * associated with this user are not affected and they will not be automatically closed on return * to the pool. */ @Override public void invalidate(PooledConnection pc) throws SQLException { PooledConnectionAndInfo info = pcMap.get(pc); if (info == null) { throw new IllegalStateException(NO_KEY_MESSAGE); } UserPassKey key = info.getUserPassKey(); try { _pool.invalidateObject(key, info); // Destroy and update pool counters _pool.clear(key); // Remove any idle instances with this key } catch (Exception ex) { throw new SQLException("Error invalidating connection", ex); } }
/** * If a fatal error occurs, close the underlying physical connection so as not to be returned in * the future */ @Override public void connectionErrorOccurred(ConnectionEvent event) { PooledConnection pc = (PooledConnection) event.getSource(); if (null != event.getSQLException()) { System.err.println( "CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR (" + event.getSQLException() + ")"); } pc.removeConnectionEventListener(this); PooledConnectionAndInfo info = pcMap.get(pc); if (info == null) { throw new IllegalStateException(NO_KEY_MESSAGE); } try { _pool.invalidateObject(info.getUserPassKey(), info); } catch (Exception e) { System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info); e.printStackTrace(); } }
/** * Attempt to retrieve a database connection using {@link #getPooledConnectionAndInfo(String, * String)} with the provided username and password. The password on the {@link * PooledConnectionAndInfo} instance returned by <code>getPooledConnectionAndInfo</code> is * compared to the <code>password</code> parameter. If the comparison fails, a database connection * using the supplied username and password is attempted. If the connection attempt fails, an * SQLException is thrown, indicating that the given password did not match the password used to * create the pooled connection. If the connection attempt succeeds, this means that the database * password has been changed. In this case, the <code>PooledConnectionAndInfo</code> instance * retrieved with the old password is destroyed and the <code>getPooledConnectionAndInfo</code> is * repeatedly invoked until a <code>PooledConnectionAndInfo</code> instance with the new password * is returned. */ @Override public Connection getConnection(String username, String password) 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, password); } catch (NoSuchElementException e) { closeDueToException(info); throw new SQLException("Cannot borrow connection from pool", e); } catch (RuntimeException e) { closeDueToException(info); throw e; } catch (SQLException e) { closeDueToException(info); throw e; } catch (Exception e) { closeDueToException(info); throw new SQLException("Cannot borrow connection from pool", e); } if (!(null == password ? null == info.getPassword() : password.equals( info.getPassword()))) { // Password on PooledConnectionAndInfo does not match try { // See if password has changed by attempting connection testCPDS(username, password); } catch (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 (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 passowrd as we pull them from the pool. */ final UserPassKey upkey = info.getUserPassKey(); final PooledConnectionManager manager = getConnectionManager(upkey); manager.invalidate(info.getPooledConnection()); // Destroy and remove from pool manager.setPassword( upkey.getPassword()); // Reset the password on the factory if using CPDSConnectionFactory info = null; for (int i = 0; i < 10; i++) { // Bound the number of retries - only needed if bad instances return try { info = getPooledConnectionAndInfo(username, password); } catch (NoSuchElementException e) { closeDueToException(info); throw new SQLException("Cannot borrow connection from pool", e); } catch (RuntimeException e) { closeDueToException(info); throw e; } catch (SQLException e) { closeDueToException(info); throw e; } catch (Exception e) { closeDueToException(info); throw new SQLException("Cannot borrow connection from pool", e); } if (info != null && password != null && password.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."); } } Connection con = info.getPooledConnection().getConnection(); try { setupDefaults(con, username); con.clearWarnings(); return con; } catch (SQLException ex) { try { con.close(); } catch (Exception exc) { getLogWriter().println("ignoring exception during close: " + exc); } throw ex; } }