You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2012/03/20 16:45:20 UTC

svn commit: r1302948 - in /tomcat/trunk/modules/jdbc-pool/src: main/java/org/apache/tomcat/jdbc/pool/ main/java/org/apache/tomcat/jdbc/pool/jmx/ test/java/org/apache/tomcat/jdbc/test/

Author: fhanik
Date: Tue Mar 20 15:45:19 2012
New Revision: 1302948

URL: http://svn.apache.org/viewvc?rev=1302948&view=rev
Log:
https://issues.apache.org/bugzilla/show_bug.cgi?id=52002 add in ability to configure pool so that connections can not be reused

Added:
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
    tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
Modified:
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java Tue Mar 20 15:45:19 2012
@@ -312,7 +312,12 @@ public class ConnectionPool {
             getProxyConstructor(con.getXAConnection() != null);
             //create the proxy
             //TODO possible optimization, keep track if this connection was returned properly, and don't generate a new facade
-            Connection connection = (Connection)proxyClassConstructor.newInstance(new Object[] { handler });
+            Connection connection = null;
+            if (getPoolProperties().getUseDisposableConnectionFacade() ) {
+                connection = (Connection)proxyClassConstructor.newInstance(new Object[] { new DisposableConnectionFacade(handler) });
+            } else {
+                connection = (Connection)proxyClassConstructor.newInstance(new Object[] {handler});
+            }
             //return the connection
             return connection;
         }catch (Exception x) {

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java Tue Mar 20 15:45:19 2012
@@ -1226,4 +1226,20 @@ public class DataSourceProxy implements 
         return getPoolProperties().getRollbackOnReturn();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
 }

Added: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java?rev=1302948&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java (added)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java Tue Mar 20 15:45:19 2012
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.jdbc.pool;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+/**
+ * A DisposableConnectionFacade object is the top most interceptor that wraps an object of type
+ * {@link PooledConnection}. The ProxyCutOffConnection intercepts two methods:
+ * <ul>
+ *   <li>{@link java.sql.Connection#close()} - returns the connection to the pool then breaks the link between cutoff and the next interceptor. May be called multiple times.</li>
+ *   <li>{@link java.lang.Object#toString()} - returns a custom string for this object</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 Kevin Grainer
+ */
+public class DisposableConnectionFacade extends JdbcInterceptor {
+    protected DisposableConnectionFacade(JdbcInterceptor interceptor) throws SQLException {
+        setUseEquals(interceptor.isUseEquals());
+        setNext(interceptor);
+    }
+
+    @Override
+    public void reset(ConnectionPool parent, PooledConnection con) {
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (compare(ISCLOSED_VAL, method) && getNext() == null) {
+            return Boolean.TRUE;
+        }
+        if (compare(CLOSE_VAL, method) && getNext() == null) {
+            return null;
+        }
+
+        try {
+            return super.invoke(proxy, method, args);
+        } catch (NullPointerException e) {
+            if (getNext() == null) {
+                if (compare(TOSTRING_VAL, method)) {
+                    return "DisposableConnectionFacade[null]";
+                }
+                throw new SQLException("Connection has already been closed.");
+            }
+
+            throw e;
+        } finally {
+            if (compare(CLOSE_VAL, method)) {
+                setNext(null);
+            }
+        }
+    }
+}

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java Tue Mar 20 15:45:19 2012
@@ -70,7 +70,7 @@ public abstract class JdbcInterceptor im
     /**
      * The next interceptor in the chain
      */
-    private JdbcInterceptor next = null;
+    private volatile JdbcInterceptor next = null;
     /**
      * Property that decides how we do string comparison, default is to use
      * {@link String#equals(Object)}. If set to <code>false</code> then the

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java Tue Mar 20 15:45:19 2012
@@ -821,4 +821,18 @@ public interface PoolConfiguration {
      */
     public boolean getRollbackOnReturn();
 
+    /**
+     * If set to true, the connection will be wrapped with facade that will disallow the connection to be used after
+     * {@link java.sql.Connection#close()} is called. If set to true, after {@link java.sql.Connection#close()} all calls except
+     * {@link java.sql.Connection#close()} and {@link java.sql.Connection#isClosed()} will throw an exception.
+     * @param useDisposableConnectionFacade
+     */
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade);
+    /**
+     * Returns true if this connection pool is configured to use a connection facade to prevent re-use of connection after
+     * {@link java.sql.Connection#close()} has been invoked
+     * @return true if {@link java.sql.Connection#close()} has been invoked.
+     */
+    public boolean getUseDisposableConnectionFacade();
+
 }

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java Tue Mar 20 15:45:19 2012
@@ -86,6 +86,7 @@ public class PoolProperties implements P
     protected boolean alternateUsernameAllowed = false;
     protected boolean commitOnReturn = false;
     protected boolean rollbackOnReturn = false;
+    protected boolean useDisposableConnectionFacade;
 
 
     /**
@@ -1194,4 +1195,29 @@ public class PoolProperties implements P
     public boolean getRollbackOnReturn() {
         return this.rollbackOnReturn;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        this.useDisposableConnectionFacade = useDisposableConnectionFacade;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return useDisposableConnectionFacade;
+    }
+
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        // TODO Auto-generated method stub
+        return super.clone();
+    }
+
+
+
 }

Modified: tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=1302948&r1=1302947&r2=1302948&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java (original)
+++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java Tue Mar 20 15:45:19 2012
@@ -777,5 +777,22 @@ public class ConnectionPool extends Noti
         return getPoolProperties().getRollbackOnReturn();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
+        getPoolProperties().setUseDisposableConnectionFacade(useDisposableConnectionFacade);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getUseDisposableConnectionFacade() {
+        return getPoolProperties().getUseDisposableConnectionFacade();
+    }
+
+
 
 }

Added: tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java?rev=1302948&view=auto
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java (added)
+++ tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java Tue Mar 20 15:45:19 2012
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.jdbc.test;
+
+import java.sql.Connection;
+import org.apache.tomcat.jdbc.test.driver.Driver;
+
+public class MultipleCloseTest extends DefaultTestCase {
+
+    public MultipleCloseTest(String name) {
+        super(name);
+    }
+
+    @Override
+    public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
+        org.apache.tomcat.jdbc.pool.DataSource ds = super.createDefaultDataSource();
+        ds.getPoolProperties().setDriverClassName(Driver.class.getName());
+        ds.getPoolProperties().setUrl(Driver.url);
+        ds.getPoolProperties().setInitialSize(0);
+        ds.getPoolProperties().setMaxIdle(1);
+        ds.getPoolProperties().setMinIdle(1);
+        ds.getPoolProperties().setMaxActive(1);
+        ds.getPoolProperties().setUseDisposableConnectionFacade(true);
+        return ds;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        Driver.reset();
+        super.tearDown();
+    }
+
+    public void testClosedConnectionsNotReused() throws Exception {
+        this.init();
+
+        Connection con1 = datasource.getConnection();
+
+        // A new connection is open
+        assertFalse(con1.isClosed());
+
+        con1.close();
+
+        // Confirm that a closed connection is closed
+        assertTrue(con1.isClosed());
+
+        // Open a new connection (This will re-use the previous pooled connection)
+        datasource.getConnection();
+
+        // A connection, once closed, should stay closed
+        assertTrue(con1.isClosed());
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


RE: svn commit: r1302948 - in /tomcat/trunk/modules/jdbc-pool/src: main/java/org/apache/tomcat/jdbc/pool/ main/java/org/apache/tomcat/jdbc/pool/jmx/ test/java/org/apache/tomcat/jdbc/test/

Posted by "Filip Hanik (mailing lists)" <de...@hanik.com>.

> -----Original Message-----
> 
> There is no need in the above clone() method.
> It has the same access level (protected) as super one.
> 
> I see that PoolProperties is written as "implements Cloneable". In
> such case the clone method is usually redeclared as public one.
[Filip Hanik] 

No, implements Cloneable , just means that the JVM wont throw an exception
if you try to call the method and it is not implemented. It lets the JVM do
the cloning for you
The IDE added in the method, and I don't see how it hurts





---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1302948 - in /tomcat/trunk/modules/jdbc-pool/src: main/java/org/apache/tomcat/jdbc/pool/ main/java/org/apache/tomcat/jdbc/pool/jmx/ test/java/org/apache/tomcat/jdbc/test/

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/3/20  <fh...@apache.org>:
> Author: fhanik
> Date: Tue Mar 20 15:45:19 2012
> New Revision: 1302948
>
> URL: http://svn.apache.org/viewvc?rev=1302948&view=rev
> Log:
> https://issues.apache.org/bugzilla/show_bug.cgi?id=52002 add in ability to configure pool so that connections can not be reused
>
> Added:
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DisposableConnectionFacade.java
>    tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/MultipleCloseTest.java
> Modified:
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/JdbcInterceptor.java
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
>    tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
>
(...)

> --- tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java (original)
> +++ tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolProperties.java Tue Mar 20 15:45:19 2012
> @@ -86,6 +86,7 @@ public class PoolProperties implements P
>     protected boolean alternateUsernameAllowed = false;
>     protected boolean commitOnReturn = false;
>     protected boolean rollbackOnReturn = false;
> +    protected boolean useDisposableConnectionFacade;
>
>
>     /**
> @@ -1194,4 +1195,29 @@ public class PoolProperties implements P
>     public boolean getRollbackOnReturn() {
>         return this.rollbackOnReturn;
>     }
> +
> +    /**
> +     * {@inheritDoc}
> +     */
> +    @Override
> +    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
> +        this.useDisposableConnectionFacade = useDisposableConnectionFacade;
> +    }
> +
> +    /**
> +     * {@inheritDoc}
> +     */
> +    @Override
> +    public boolean getUseDisposableConnectionFacade() {
> +        return useDisposableConnectionFacade;
> +    }
> +
> +    @Override
> +    protected Object clone() throws CloneNotSupportedException {
> +        // TODO Auto-generated method stub
> +        return super.clone();
> +    }

There is no need in the above clone() method.
It has the same access level (protected) as super one.

I see that PoolProperties is written as "implements Cloneable". In
such case the clone method is usually redeclared as public one.

> +
> +
> +
>  }
>

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org