Author: fhanik Date: Tue Jul 14 00:08:01 2009 New Revision: 793761 URL: http://svn.apache.org/viewvc?rev=793761&view=rev Log: more javadoc and corrections
Modified: tomcat/trunk/modules/jdbc-pool/build.xml tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CreateTestTable.java Modified: tomcat/trunk/modules/jdbc-pool/build.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/build.xml?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/build.xml (original) +++ tomcat/trunk/modules/jdbc-pool/build.xml Tue Jul 14 00:08:01 2009 @@ -98,9 +98,10 @@ </xslt> <move tofile="${basedir}/java/org/apache/tomcat/jdbc/pool/package.html" file="${basedir}/java/org/apache/tomcat/jdbc/pool/jdbc-pool.html"/> - <javadoc sourcepath="${basedir}/java" destdir="${tomcat.api}" verbose="false"> + <javadoc sourcepath="${basedir}/java" destdir="${tomcat.api}" verbose="false" + link="http://java.sun.com/javase/6/docs/api/"> <classpath refid="tomcat.jdbc.classpath"/> - </javadoc> + </javadoc> <!-- connection pool API file--> <jar jarfile="${tomcat-jdbc-api.jar}" update="true"> <fileset dir="${tomcat.api}"/> Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Tue Jul 14 00:08:01 2009 @@ -499,6 +499,7 @@ if (con.release()) { //counter only decremented once size.addAndGet(-1); + con.setHandler(null); } } finally { con.unlock(); Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java (original) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java Tue Jul 14 00:08:01 2009 @@ -24,30 +24,37 @@ /** * Abstract class that is to be extended for implementations of interceptors. + * Everytime an operation is called on the {...@link java.sql.Connection} object the + * {...@link #invoke(Object, Method, Object[])} method on the interceptor will be called. + * Interceptors are useful to change or improve behavior of the connection pool.<br/> + * Interceptors can receive a set of properties. Each sub class is responsible for parsing the properties during runtime when they + * are needed or simply override the {...@link #setProperties(Map)} method. + * Properties arrive in a key-value pair of Strings as they were received through the configuration. + * This method is called once per cached connection object when the object is first configured. * * @author Filip Hanik * @version 1.0 */ public abstract class JdbcInterceptor implements InvocationHandler { /** - * java.sql.Connection.close() + * {...@link java.sql.Connection#close()} method name */ public static final String CLOSE_VAL = "close"; /** - * java.sql.Connection.toString() + * {...@link Object#toString()} method name */ public static final String TOSTRING_VAL = "toString"; /** - * java.sql.Connection.isClosed() + * {...@link java.sql.Connection#isClosed()} method name */ public static final String ISCLOSED_VAL = "isClosed"; /** - * javax.sql.DataSource.getConnection() + * {...@link javax.sql.PooledConnection#getConnection()} method name */ public static final String GETCONNECTION_VAL = "getConnection"; /** - * Properties for this interceptor + * Properties for this interceptor. */ protected Map<String,InterceptorProperty> properties = null; @@ -67,9 +74,10 @@ } /** - * Gets invoked each time an operation on java.sql.Connection is invoked. + * Gets invoked each time an operation on {...@link java.sql.Connection} is invoked. * {...@inheritdoc} */ + @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (getNext()!=null) return getNext().invoke(this,method,args); else throw new NullPointerException(); @@ -121,13 +129,15 @@ * Gets called each time the connection is borrowed from the pool * This means that if an interceptor holds a reference to the connection * the interceptor can be reused for another connection. + * <br/> + * This method may be called with null as both arguments when we are closing down the connection. * @param parent - the connection pool owning the connection * @param con - the pooled connection */ public abstract void reset(ConnectionPool parent, PooledConnection con); /** - * + * Returns the properties configured for this interceptor * @return the configured properties for this interceptor */ public Map<String,InterceptorProperty> getProperties() { @@ -137,6 +147,7 @@ /** * Called during the creation of an interceptor * The properties can be set during the configuration of an interceptor + * Override this method to perform type casts between string values and object properties * @param properties */ public void setProperties(Map<String,InterceptorProperty> properties) { Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java (original) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java Tue Jul 14 00:08:01 2009 @@ -31,7 +31,7 @@ /** * Represents a pooled connection - * and holds a reference to the java.sql.Connection object + * and holds a reference to the {...@link java.sql.Connection} object * @author Filip Hanik * @version 1.0 */ @@ -69,7 +69,7 @@ /** * The underlying database connection */ - private java.sql.Connection connection; + private volatile java.sql.Connection connection; /** * When we track abandon traces, this string holds the thread dump */ @@ -108,16 +108,30 @@ * so that we don't create a new list of interceptors each time we borrow * the connection */ - private WeakReference<JdbcInterceptor> handler = null; + private volatile JdbcInterceptor handler = null; private AtomicBoolean released = new AtomicBoolean(false); + /** + * Constructor + * @param prop - pool properties + * @param parent - the parent connection pool + */ public PooledConnection(PoolConfiguration prop, ConnectionPool parent) { instanceCount = counter.addAndGet(1); poolProperties = prop; this.parent = parent; } + /** + * Connects the underlying connection to the database. + * @throws SQLException if the method {...@link #release()} has been called. + * @throws SQLException if driver instantiation fails + * @throws SQLException if a call to {...@link java.sql.Driver#connect(String, java.util.Properties)} fails. + * @throws SQLException if default properties are configured and a call to + * {...@link java.sql.Connection#setAutoCommit(boolean)}, {...@link java.sql.Connection#setCatalog(String)}, + * {...@link java.sql.Connection#setTransactionIsolation(int)} or {...@link java.sql.Connection#setReadOnly(boolean)} fails. + */ public void connect() throws SQLException { if (released.get()) throw new SQLException("A connection once released, can't be reestablished."); if (connection != null) { @@ -185,11 +199,20 @@ return connection!=null; } + /** + * Issues a call to {...@link #disconnect(boolean)} with the argument false followed by a call to + * {...@link #connect()} + * @throws SQLException if the call to {...@link #connect()} fails. + */ public void reconnect() throws SQLException { this.disconnect(false); this.connect(); } //reconnect + /** + * Disconnects the connection. All exceptions are logged using debug level. + * @param finalize if set to true, a call to {...@link ConnectionPool#finalize(PooledConnection)} is called. + */ private void disconnect(boolean finalize) { if (isDiscarded()) { return; @@ -226,6 +249,12 @@ } //end if } + /** + * Returns true if the connection pool is configured + * to do validation for a certain action. + * @param action + * @return + */ private boolean doValidate(int action) { if (action == PooledConnection.VALIDATE_BORROW && poolProperties.isTestOnBorrow()) @@ -254,6 +283,18 @@ return validate(validateAction,null); } + /** + * Validates a connection. + * @param validateAction the action used. One of {...@link #VALIDATE_BORROW}, {...@link #VALIDATE_IDLE}, + * {...@link #VALIDATE_INIT} or {...@link #VALIDATE_RETURN} + * @param sql the SQL to be used during validation. If the {...@link PoolConfiguration#setInitSQL(String)} has been called with a non null + * value and the action is {...@link #VALIDATE_INIT} the init SQL will be used for validation. + * + * @return true if the connection was validated successfully. It returns true even if validation was not performed, such as when + * {...@link PoolConfiguration#setValidationInterval(long)} has been called with a positive value. + * @return false if the validation failed. The caller should close the connection if false is returned since a session could have been left in + * an unknown state during initialization. + */ public boolean validate(int validateAction,String sql) { if (this.isDiscarded()) { return false; @@ -279,8 +320,9 @@ this.poolProperties.getValidationInterval()) { return true; } + Statement stmt = null; try { - Statement stmt = connection.createStatement(); + stmt = connection.createStatement(); boolean exec = stmt.execute(query); stmt.close(); this.lastValidated = now; @@ -288,6 +330,8 @@ } catch (Exception ignore) { if (log.isDebugEnabled()) log.debug("Unable to validate object:",ignore); + if (stmt!=null) + try { stmt.close();} catch (Exception ignore2){} } return false; } //validate @@ -295,6 +339,7 @@ /** * The time limit for how long the object * can remain unused before it is released + * @return {...@link PoolConfiguration#getMinEvictableIdleTimeMillis()} */ public long getReleaseTime() { return this.poolProperties.getMinEvictableIdleTimeMillis(); @@ -302,6 +347,11 @@ /** * This method is called if (Now - timeCheckedIn > getReleaseTime()) + * This method disconnects the connection, logs an error in debug mode if it happens + * then sets the {...@link #released} flag to false. Any attempts to connect this cached object again + * will fail per {...@link #connect()} + * The connection pool uses the atomic return value to decrement the pool size counter. + * @return true if this is the first time this method has been called. false if this method has been called before. */ public boolean release() { try { @@ -318,51 +368,97 @@ /** * The pool will set the stack trace when it is check out and * checked in + * @param trace the stack trace for this connection */ public void setStackTrace(String trace) { abandonTrace = trace; } + /** + * Returns the stack trace from when this connection was borrowed. Can return null if no stack trace was set. + * @return the stack trace or null of no trace was set + */ public String getStackTrace() { return abandonTrace; } + /** + * Sets a timestamp on this connection. A timestamp usually means that some operation + * performed successfully. + * @param timestamp the timestamp as defined by {...@link System#currentTimeMillis()} + */ public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + /** + * An interceptor can call this method with the value true, and the connection will be closed when it is returned to the pool. + * @param discarded - only valid value is true + * @throws IllegalStateException if this method is called with the value false and the value true has already been set. + */ public void setDiscarded(boolean discarded) { if (this.discarded && !discarded) throw new IllegalStateException("Unable to change the state once the connection has been discarded"); this.discarded = discarded; } + /** + * Set the timestamp the connection was last validated. + * This flag is used to keep track when we are using a {...@link PoolConfiguration#setValidationInterval(long) validation-interval}. + * @param lastValidated a timestamp as defined by {...@link System#currentTimeMillis()} + */ public void setLastValidated(long lastValidated) { this.lastValidated = lastValidated; } + /** + * Sets the pool configuration for this connection and connection pool. + * Object is shared with the {...@link ConnectionPool} + * @param poolProperties + */ public void setPoolProperties(PoolConfiguration poolProperties) { this.poolProperties = poolProperties; } + /** + * Return the timestamps of last pool action. Timestamps are typically set when connections + * are borrowed from the pool. It is used to keep track of {...@link PoolConfiguration#setRemoveAbandonedTimeout(int) abandon-timeouts}. + * This timestamp can also be reset by the {...@link org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer#invoke(Object, java.lang.reflect.Method, Object[])} + * @return the timestamp of the last pool action as defined by {...@link System#currentTimeMillis()} + */ public long getTimestamp() { return timestamp; } + /** + * Returns the discarded flag. + * @return the discarded flag. If the value is true, + * either {...@link #disconnect(boolean)} has been called or it will be called when the connection is returned to the pool. + */ public boolean isDiscarded() { return discarded; } + /** + * Returns the timestamp of the last successful validation query execution. + * @return the timestamp of the last successful validation query execution as defined by {...@link System#currentTimeMillis()} + */ public long getLastValidated() { return lastValidated; } + /** + * Returns the configuration for this connection and pool + * @return the configuration for this connection and pool + */ public PoolConfiguration getPoolProperties() { return poolProperties; } /** - * Locks the connection only if the sweeper thread is enabled + * Locks the connection only if either {...@link PoolConfiguration#isPoolSweeperEnabled()} or + * {...@link PoolConfiguration#getUseLock()} return true. The per connection lock ensures thread safety is + * multiple threads are performing operations on the connection. * Otherwise this is a noop for performance */ public void lock() { @@ -386,13 +482,18 @@ /** * Returns the underlying connection * @return the underlying JDBC connection as it was returned from the JDBC driver + * @see javax.sql.PooledConnection#getConnection() */ public java.sql.Connection getConnection() { return this.connection; } - + /** + * Returns the timestamp of when the connection was last connected to the database. + * ie, a successful call to {...@link java.sql.Driver#connect(String, java.util.Properties)}. + * @return the timestamp when this connection was created as defined by {...@link System#currentTimeMillis()} + */ public long getLastConnected() { return lastConnected; } @@ -402,27 +503,28 @@ * @return the first interceptor for this connection */ public JdbcInterceptor getHandler() { - return (handler!=null)?handler.get():null; + return handler; } public void setHandler(JdbcInterceptor handler) { - if (handler==null) { - if (this.handler!=null) this.handler.clear(); - } else if (this.handler==null) { - this.handler = new WeakReference<JdbcInterceptor>(handler); - } else if (this.handler.get()==null) { - this.handler.clear(); - this.handler = new WeakReference<JdbcInterceptor>(handler); - } else if (this.handler.get()!=handler) { - this.handler.clear(); - this.handler = new WeakReference<JdbcInterceptor>(handler); - } + if (this.handler!=null && this.handler!=handler) { + JdbcInterceptor interceptor = this.handler; + while (interceptor!=null) { + interceptor.reset(null, null); + interceptor = interceptor.getNext(); + }//while + }//end if + this.handler = handler; } public String toString() { return "PooledConnection["+(connection!=null?connection.toString():"null")+"]"; } + /** + * Returns true if this connection has been released and wont be reused. + * @return true if the method {...@link #release()} has been called + */ public boolean isReleased() { return released.get(); } Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java (original) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ProxyConnection.java Tue Jul 14 00:08:01 2009 @@ -20,6 +20,15 @@ import java.lang.reflect.Method; import java.sql.SQLException; /** + * A ProxyConnection object is the bottom most interceptor that wraps an object of type + * {...@link PooledConnection}. The ProxyConnection intercepts three methods: + * <ul> + * <li>{...@link java.sql.Connection#close()} - returns the connection to the pool. May be called multiple times.</li> + * <li>{...@link java.lang.Object#toString()} - returns a custom string for this object</li> + * <li>{...@link javax.sql.PooledConnection#getConnection()} - returns the underlying connection</li> + * </ul> + * By default method comparisons is done on a String reference level, unless the {...@link PoolConfiguration#setUseEquals(boolean)} has been called + * with a <code>true</code> argument. * @author Filip Hanik */ public class ProxyConnection extends JdbcInterceptor { Modified: tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CreateTestTable.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CreateTestTable.java?rev=793761&r1=793760&r2=793761&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CreateTestTable.java (original) +++ tomcat/trunk/modules/jdbc-pool/test/org/apache/tomcat/jdbc/test/CreateTestTable.java Tue Jul 14 00:08:01 2009 @@ -63,7 +63,6 @@ public void testPopulateData() throws Exception { init(); datasource.setJdbcInterceptors(ResetAbandonedTimer.class.getName()); - System.out.println("FILIP Using URL:"+this.datasource.getUrl()); String insert = "insert into test values (?,?,?,?,?)"; this.init(); this.datasource.setRemoveAbandoned(false); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org