You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2006/04/23 15:22:54 UTC

svn commit: r396269 - /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java

Author: kahatlen
Date: Sun Apr 23 06:22:52 2006
New Revision: 396269

URL: http://svn.apache.org/viewcvs?rev=396269&view=rev
Log:
DERBY-1234: Verify that we raise SQLException when calling methods on
closed java.sql objects

Added test (jdbc4/ClosedObjectTest.junit) which checks whether
exceptions are thrown when calling methods on closed objects. The test
is not enabled in any suite.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java   (with props)

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java?rev=396269&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java Sun Apr 23 06:22:52 2006
@@ -0,0 +1,762 @@
+/*
+ * Derby - org.apache.derbyTesting.functionTests.tests.jdbc4.ClosedObjectTest
+ *
+ * Copyright 2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed 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.derbyTesting.functionTests.tests.jdbc4;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.CallableStatement;
+import java.sql.ClientInfoException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Properties;
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.functionTests.util.BaseJDBCTestCase;
+
+/**
+ * Test that all methods on <code>ResultSet</code>,
+ * <code>Statement</code>, <code>PreparedStatement</code>,
+ * <code>CallableStatement</code> and <code>Connection</code> objects
+ * throw the appropriate exceptions when the objects are closed.
+ */
+public class ClosedObjectTest extends BaseJDBCTestCase {
+    /** The method to test. */
+    private final Method method_;
+    /** Test decorator which provides a closed object to invoke a
+     * method on. */
+    private final ObjectDecorator decorator_;
+    /** Name of the test. */
+    private String name_;
+
+    /**
+     * Creates a new <code>ClosedObjectTest</code> instance.
+     *
+     * @param method the method to test
+     * @param decorator a decorator which provides a closed object
+     */
+    public ClosedObjectTest(Method method, ObjectDecorator decorator) {
+        super("testClosedObjects");
+        method_ = method;
+        decorator_ = decorator;
+        // setting name temporarily, we don't know the real class name yet
+        name_ = method.getDeclaringClass().getName() + "." + method.getName();
+    }
+
+    /**
+     * Gets the name of the test.
+     *
+     * @return name of the test
+     */
+    public String getName() {
+        return name_;
+    }
+
+    /**
+     * Runs a test case. A method is called on a closed object, and it
+     * is checked that the appropriate exception is thrown.
+     *
+     * @exception Throwable if an error occurs
+     */
+    public void testClosedObjects() throws Throwable {
+        try {
+            Object object = decorator_.getClosedObject();
+
+            // update name of test with real class name
+            name_ = object.getClass() + "." + method_.getName();
+
+            method_.invoke(object,
+                           getNullArguments(method_.getParameterTypes()));
+            assertFalse("No exception was thrown",
+                        decorator_.expectsException(method_));
+        } catch (InvocationTargetException ite) {
+            try {
+                throw ite.getCause();
+            } catch (SQLFeatureNotSupportedException fnse) {
+                // if we don't support the method, it is OK that we
+                // throw this exception
+            } catch (SQLException sqle) {
+                decorator_.checkException(method_, sqle);
+            }
+        }
+    }
+
+    /**
+     * Creates the test suite and fills it with tests using
+     * <code>DataSource</code>, <code>ConnectionPoolDataSource</code>
+     * and <code>XADataSource</code> to obtain objects.
+     *
+     * @return a <code>Test</code> value
+     * @exception Exception if an error occurs while building the test suite
+     */
+    public static Test suite() throws Exception {
+        TestSuite topSuite = new TestSuite();
+
+        TestSuite dsSuite = new TestSuite();
+        DataSourceDecorator dsDecorator = new DataSourceDecorator(dsSuite);
+        topSuite.addTest(dsDecorator);
+        fillDataSourceSuite(dsSuite, dsDecorator);
+
+        TestSuite poolSuite = new TestSuite();
+        PoolDataSourceDecorator poolDecorator =
+            new PoolDataSourceDecorator(poolSuite);
+        topSuite.addTest(poolDecorator);
+        fillDataSourceSuite(poolSuite, poolDecorator);
+
+        TestSuite xaSuite = new TestSuite();
+        XADataSourceDecorator xaDecorator = new XADataSourceDecorator(xaSuite);
+        topSuite.addTest(xaDecorator);
+        fillDataSourceSuite(xaSuite, xaDecorator);
+
+        return topSuite;
+    }
+
+    /**
+     * Fills a test suite which is contained in a
+     * <code>DataSourceDecorator</code> with tests for
+     * <code>ResultSet</code>, <code>Statement</code>,
+     * <code>PreparedStatement</code>, <code>CallableStatement</code>
+     * and <code>Connection</code>.
+     *
+     * @param suite the test suite to fill
+     * @param dsDecorator the decorator for the test suite
+     * @exception Exception if an error occurs while filling the suite
+     */
+    private static void fillDataSourceSuite(TestSuite suite,
+                                            DataSourceDecorator dsDecorator)
+        throws Exception
+    {
+        TestSuite rsSuite = new TestSuite();
+        ResultSetObjectDecorator rsDecorator =
+            new ResultSetObjectDecorator(rsSuite, dsDecorator);
+        suite.addTest(rsDecorator);
+        fillObjectSuite(rsSuite, rsDecorator, ResultSet.class);
+
+        TestSuite stmtSuite = new TestSuite();
+        StatementObjectDecorator stmtDecorator =
+            new StatementObjectDecorator(stmtSuite, dsDecorator);
+        suite.addTest(stmtDecorator);
+        fillObjectSuite(stmtSuite, stmtDecorator, Statement.class);
+
+        TestSuite psSuite = new TestSuite();
+        PreparedStatementObjectDecorator psDecorator =
+            new PreparedStatementObjectDecorator(psSuite, dsDecorator);
+        suite.addTest(psDecorator);
+        fillObjectSuite(psSuite, psDecorator, PreparedStatement.class);
+
+        TestSuite csSuite = new TestSuite();
+        CallableStatementObjectDecorator csDecorator =
+            new CallableStatementObjectDecorator(csSuite, dsDecorator);
+        suite.addTest(csDecorator);
+        fillObjectSuite(csSuite, csDecorator, CallableStatement.class);
+
+        TestSuite connSuite = new TestSuite();
+        ConnectionObjectDecorator connDecorator =
+            new ConnectionObjectDecorator(connSuite, dsDecorator);
+        suite.addTest(connDecorator);
+        fillObjectSuite(connSuite, connDecorator, Connection.class);
+    }
+
+    /**
+     * Fills a suite with tests for all the methods of an interface.
+     *
+     * @param suite the suite to fill
+     * @param decorator a decorator for the test (used for obtaining a
+     * closed object to test the method on)
+     * @param iface the interface which contains the methods to test
+     * @exception Exception if an error occurs while filling the suite
+     */
+    private static void fillObjectSuite(TestSuite suite,
+                                        ObjectDecorator decorator,
+                                        Class iface)
+        throws Exception
+    {
+        for (Method m : iface.getMethods()) {
+            ClosedObjectTest cot = new ClosedObjectTest(m, decorator);
+            suite.addTest(cot);
+        }
+    }
+
+    /**
+     * Takes an array of classes and returns an array of objects with
+     * null values compatible with the classes. Helper method for
+     * converting a parameter list to an argument list.
+     *
+     * @param params a <code>Class[]</code> value
+     * @return an <code>Object[]</code> value
+     */
+    private static Object[] getNullArguments(Class[] params) {
+        Object[] args = new Object[params.length];
+        for (int i = 0; i < params.length; i++) {
+            args[i] = getNullValueForType(params[i]);
+        }
+        return args;
+    }
+
+    /**
+     * Returns a null value compatible with the class. For instance,
+     * return <code>Boolean.FALSE</code> for primitive booleans, 0 for
+     * primitive integers and <code>null</code> for non-primitive
+     * types.
+     *
+     * @param type a <code>Class</code> value
+     * @return a null value
+     */
+    private static Object getNullValueForType(Class type) {
+        if (!type.isPrimitive()) {
+            return null;
+        }
+        if (type == Boolean.TYPE) {
+            return Boolean.FALSE;
+        }
+        if (type == Character.TYPE) {
+            return new Character((char) 0);
+        }
+        if (type == Byte.TYPE) {
+            return new Byte((byte) 0);
+        }
+        if (type == Short.TYPE) {
+            return new Short((short) 0);
+        }
+        if (type == Integer.TYPE) {
+            return new Integer(0);
+        }
+        if (type == Long.TYPE) {
+            return new Long(0L);
+        }
+        if (type == Float.TYPE) {
+            return new Float(0f);
+        }
+        if (type == Double.TYPE) {
+            return new Double(0d);
+        }
+        fail("Don't know how to handle type " + type);
+        return null;            // unreachable statement
+    }
+
+    /**
+     * Abstract decorator class with functionality for obtaining a
+     * closed object.
+     */
+    private static abstract class ObjectDecorator extends TestSetup {
+        /** Decorator which provides a connection. */
+        private final DataSourceDecorator decorator_;
+        /** The closed object. Must be set by a sub-class. */
+        protected Object object_;
+
+        /**
+         * Creates a new <code>ObjectDecorator</code> instance.
+         *
+         * @param test a test or suite to decorate
+         * @param decorator a decorator which provides a connection
+         */
+        public ObjectDecorator(Test test, DataSourceDecorator decorator) {
+            super(test);
+            decorator_ = decorator;
+        }
+
+        /**
+         * Returns the closed object.
+         *
+         * @return a closed object
+         */
+        public Object getClosedObject() {
+            return object_;
+        }
+
+        /**
+         * Checks whether a method expects an exception to be thrown
+         * when the object is closed. Currently, only
+         * <code>close()</code> and <code>isClosed()</code> don't
+         * expect exceptions.
+         *
+         * @param method a method
+         * @return <code>true</code> if an exception is expected
+         */
+        public boolean expectsException(Method method) {
+            return
+                !(method.getName().equals("close") ||
+                  method.getName().equals("isClosed"));
+        }
+
+        /**
+         * Checks whether an exception is of the expected type for
+         * that method.
+         *
+         * @param method a method
+         * @param sqle an exception
+         * @exception SQLException if the exception was not expected
+         */
+        public final void checkException(Method method, SQLException sqle)
+            throws SQLException
+        {
+            if (!expectsException(method)) {
+                throw sqle;
+            }
+            checkSQLState(method, sqle);
+        }
+
+        /**
+         * Checks whether the SQL state is as expected.
+         *
+         * @param method a <code>Method</code> value
+         * @param sqle a <code>SQLException</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected abstract void checkSQLState(Method method,
+                                              SQLException sqle)
+            throws SQLException;
+
+        /**
+         * Helper method for creating a connection.
+         *
+         * @return a connection
+         * @exception SQLException if an error occurs
+         */
+        protected Connection createConnection() throws SQLException {
+            return decorator_.newConnection();
+        }
+
+        /**
+         * Helper method for creating a statement.
+         *
+         * @return a statement
+         * @exception SQLException if an error occurs
+         */
+        protected Statement createStatement() throws SQLException {
+            return decorator_.getConnection().createStatement();
+        }
+
+        /**
+         * Helper method for creating a prepared statement.
+         *
+         * @param sql statement text
+         * @return a prepared statement
+         * @exception SQLException if an error occurs
+         */
+        protected PreparedStatement prepareStatement(String sql)
+            throws SQLException
+        {
+            return decorator_.getConnection().prepareStatement(sql);
+        }
+
+        /**
+         * Helper method for creating a callable statement.
+         *
+         * @param call statement text
+         * @return a callable statement
+         * @exception SQLException if an error occurs
+         */
+        protected CallableStatement prepareCall(String call)
+            throws SQLException
+        {
+            return decorator_.getConnection().prepareCall(call);
+        }
+    }
+
+    /**
+     * Decorator class for testing methods on a closed result set.
+     */
+    private static class ResultSetObjectDecorator extends ObjectDecorator {
+        /** Statement used for creating the result set to test. */
+        private Statement stmt_;
+
+        /**
+         * Creates a new <code>ResultSetObjectDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         * @param decorator decorator used for obtaining a statement
+         */
+        public ResultSetObjectDecorator(Test test,
+                                        DataSourceDecorator decorator) {
+            super(test, decorator);
+        }
+
+        /**
+         * Sets up the test. Creates a result set and closes it.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void setUp() throws SQLException {
+            stmt_ = createStatement();
+            ResultSet rs = stmt_.executeQuery("VALUES(1)");
+            rs.close();
+            object_ = rs;
+        }
+
+        /**
+         * Tears down the test. Closes open resources.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void tearDown() throws SQLException {
+            stmt_.close();
+        }
+
+        /**
+         * Checks whether the exception has the expected SQL state
+         * (XCL16 - result set is closed).
+         *
+         * @param method a <code>Method</code> value
+         * @param sqle a <code>SQLException</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected void checkSQLState(Method method, SQLException sqle)
+            throws SQLException
+        {
+            if (sqle.getSQLState().equals("XCL16")) {
+                // everything is OK, do nothing
+            } else {
+                // unexpected exception
+                throw sqle;
+            }
+        }
+    }
+
+    /**
+     * Decorator class for testing methods on a closed statement.
+     */
+    private static class StatementObjectDecorator extends ObjectDecorator {
+        /**
+         * Creates a new <code>StatementObjectDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         * @param decorator decorator which provides a statement
+         */
+        public StatementObjectDecorator(Test test,
+                                        DataSourceDecorator decorator) {
+            super(test, decorator);
+        }
+
+        /**
+         * Sets up the test. Creates a statement and closes it.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void setUp() throws SQLException {
+            Statement stmt = createStatement();
+            stmt.close();
+            object_ = stmt;
+        }
+
+        /**
+         * Checks whether the exception has the expected SQL state
+         * (statement is closed). When using embedded, XJ012 is
+         * expected. When using the client driver, XCL31 is expected.
+         *
+         * @param method a <code>Method</code> value
+         * @param sqle a <code>SQLException</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected void checkSQLState(Method method, SQLException sqle)
+            throws SQLException
+        {
+            String sqlState = sqle.getSQLState();
+            if (usingEmbedded() && sqlState.equals("XJ012")) {
+                // expected, do nothing
+            } else if (usingDerbyNetClient() && sqlState.equals("XCL31")) {
+                // expected, do nothing
+            } else {
+                // unexpected exception
+                throw sqle;
+            }
+        }
+    }
+
+    /**
+     * Decorator class for testing methods on a closed prepared statement.
+     */
+    private static class PreparedStatementObjectDecorator
+        extends StatementObjectDecorator
+    {
+        /**
+         * Creates a new <code>PreparedStatementObjectDecorator</code>
+         * instance.
+         *
+         * @param test the test to decorate
+         * @param decorator decorator which provides a prepared statement
+         */
+        public PreparedStatementObjectDecorator(Test test,
+                                                DataSourceDecorator decorator)
+        {
+            super(test, decorator);
+        }
+
+        /**
+         * Sets up the test. Prepares a statement and closes it.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void setUp() throws SQLException {
+            PreparedStatement ps = prepareStatement("VALUES(1)");
+            ps.close();
+            object_ = ps;
+        }
+
+        /**
+         * Checks whether the exception has the expected SQL state
+         * (statement is closed), or XJ016 indicating it is a
+         * Statement method not meant to be invoked on a
+         * PreparedStatement.
+         *
+         * @param method a <code>Method</code> value
+         * @param sqle a <code>SQLException</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected void checkSQLState(Method method, SQLException sqle)
+            throws SQLException
+        {
+            if (method.getDeclaringClass() == Statement.class &&
+                sqle.getSQLState().equals("XJ016")) {
+                // XJ016 is "blah,blah not allowed on a prepared
+                // statement", so it's OK to get this one
+            } else {
+                super.checkSQLState(method, sqle);
+            }
+
+        }
+    }
+
+    /**
+     * Decorator class for testing methods on a closed callable statement.
+     */
+    private static class CallableStatementObjectDecorator
+        extends PreparedStatementObjectDecorator
+    {
+        /**
+         * Creates a new <code>CallableStatementObjectDecorator</code>
+         * instance.
+         *
+         * @param test the test to decorate
+         * @param decorator decorator which provides a callable statement
+         */
+        public CallableStatementObjectDecorator(Test test,
+                                                DataSourceDecorator decorator)
+        {
+            super(test, decorator);
+        }
+
+        /**
+         * Sets up the test. Prepares a call and closes the statement.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void setUp() throws SQLException {
+            CallableStatement cs =
+                prepareCall("CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1)");
+            cs.close();
+            object_ = cs;
+        }
+    }
+
+    /**
+     * Decorator class for testing methods on a closed connection.
+     */
+    private static class ConnectionObjectDecorator extends ObjectDecorator {
+        /**
+         * Creates a new <code>ConnectionObjectDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         * @param decorator decorator which provides a connection
+         */
+        public ConnectionObjectDecorator(Test test,
+                                         DataSourceDecorator decorator) {
+            super(test, decorator);
+        }
+
+        /**
+         * Sets up the test. Creates a connection and closes it.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public void setUp() throws SQLException {
+            Connection conn = createConnection();
+            conn.rollback();    // cannot close active transactions
+            conn.close();
+            object_ = conn;
+        }
+
+        /**
+         * Checks that the exception has an expected SQL state (08003
+         * - no current connection). Also accept
+         * <code>ClientInfoException</code>s from
+         * <code>setClientInfo()</code>.
+         *
+         * @param method a <code>Method</code> value
+         * @param sqle a <code>SQLException</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected void checkSQLState(Method method, SQLException sqle)
+            throws SQLException
+        {
+            if (sqle instanceof ClientInfoException &&
+                method.getName().equals("setClientInfo") &&
+                Arrays.asList(method.getParameterTypes())
+                .equals(Arrays.asList(new Class[] { Properties.class }))) {
+                // setClientInfo(Properties) should throw
+                // ClientInfoException, so this is OK
+            } else if (sqle.getSQLState().equals("08003")) {
+                // expected, connection closed
+            } else {
+                // unexpected exception
+                throw sqle;
+            }
+        }
+    }
+
+    /**
+     * Decorator class used for obtaining connections through a
+     * <code>DataSource</code>.
+     */
+    private static class DataSourceDecorator extends TestSetup {
+        /** Connection shared by many tests. */
+        private Connection connection_;
+
+        /**
+         * Creates a new <code>DataSourceDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         */
+        public DataSourceDecorator(Test test) {
+            super(test);
+        }
+
+        /**
+         * Sets up the test by creating a connection.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public final void setUp() throws SQLException {
+            connection_ = newConnection();
+        }
+
+        /**
+         * Gets the connection created when the test was set up.
+         *
+         * @return a <code>Connection</code> value
+         */
+        public final Connection getConnection() {
+            return connection_;
+        }
+
+        /**
+         * Creates a new connection with auto-commit set to false.
+         *
+         * @return a <code>Connection</code> value
+         * @exception SQLException if an error occurs
+         */
+        public final Connection newConnection() throws SQLException {
+            Connection conn = newConnection_();
+            conn.setAutoCommit(false);
+            return conn;
+        }
+
+        /**
+         * Tears down the test and closes the connection.
+         *
+         * @exception SQLException if an error occurs
+         */
+        public final void tearDown() throws SQLException {
+            connection_.rollback();
+            connection_.close();
+        }
+
+        /**
+         * Creates a new connection using a <code>DataSource</code>.
+         *
+         * @return a <code>Connection</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected Connection newConnection_() throws SQLException {
+            DataSource ds = getDataSource();
+            return ds.getConnection(CONFIG.getUserName(),
+                                    CONFIG.getUserPassword());
+        }
+    }
+
+    /**
+     * Decorator class used for obtaining connections through a
+     * <code>ConnectionPoolDataSource</code>.
+     */
+    private static class PoolDataSourceDecorator extends DataSourceDecorator {
+        /**
+         * Creates a new <code>PoolDataSourceDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         */
+        public PoolDataSourceDecorator(Test test) {
+            super(test);
+        }
+
+        /**
+         * Creates a new connection using a
+         * <code>ConnectionPoolDataSource</code>.
+         *
+         * @return a <code>Connection</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected Connection newConnection_() throws SQLException {
+            ConnectionPoolDataSource ds = getConnectionPoolDataSource();
+            PooledConnection pc =
+                ds.getPooledConnection(CONFIG.getUserName(),
+                                       CONFIG.getUserPassword());
+            return pc.getConnection();
+        }
+    }
+
+    /**
+     * Decorator class used for obtaining connections through an
+     * <code>XADataSource</code>.
+     */
+    private static class XADataSourceDecorator extends DataSourceDecorator {
+        /**
+         * Creates a new <code>XADataSourceDecorator</code> instance.
+         *
+         * @param test the test to decorate
+         */
+        public XADataSourceDecorator(Test test) {
+            super(test);
+        }
+
+        /**
+         * Creates a new connection using an <code>XADataSource</code>.
+         *
+         * @return a <code>Connection</code> value
+         * @exception SQLException if an error occurs
+         */
+        protected Connection newConnection_() throws SQLException {
+            XADataSource ds = getXADataSource();
+            XAConnection xac = ds.getXAConnection(CONFIG.getUserName(),
+                                                  CONFIG.getUserPassword());
+            return xac.getConnection();
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ClosedObjectTest.java
------------------------------------------------------------------------------
    svn:eol-style = native