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 ab...@apache.org on 2007/04/22 02:08:29 UTC

svn commit: r531129 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ client/org/apache/derby/jdbc/ engine/org/apache/derby/jdbc/ testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ testing/or...

Author: abrown
Date: Sat Apr 21 17:08:27 2007
New Revision: 531129

URL: http://svn.apache.org/viewvc?view=rev&rev=531129
Log:
DERBY-2488: Patch to ensure that JDBC 4 Pooled and XA connections are returned
from JDBC 3 DataSources if the app is running with Java SE 6.  In particular:

  1. Adds two methods, "getNewPooledConnection()" and "getNewXAConnection()",
     to the Driver30 class and makes those methods return JDBC 3 objects.

  2. Overides the two methods from #1 in Driver40 to return JDBC 4 objects.

  3. Changes the "createPooledConnection()" method and "createXAConnection()"
     methods in EmbeddedConnectionPoolDataSource and EmbeddedXADataSource
     (respectively) to call the new methods on the DriverXX object returned
     from the existing "findDriver()" method.

  4. Removes the now unused "createPooledConnection()" method from
     EmbedConnectionionPoolDataSource40, and removes "createXAConnection()"
     from EmbedXADataSource40.

  5. Changes ClientXADataSource, which had a problem similar to the Embedded
     data sources, to match the behavior of ClientConnectionPoolDataSource
     so that client now correctly returns JDBC 4 objects for Java SE 6 apps.

  6. Includes a new test, jdbc4/JDBC4FromJDBC3DataSourceTest, which verifies
     that JDBC 4 connections will be returned from JDBC 3 data sources if the
     JDK in use is JDK 1.6. 


Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/JDBC4FromJDBC3DataSourceTest.java   (with props)
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientJDBCObjectFactory.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl40.java
    db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java
    db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource40.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver30.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver40.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource40.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource.java
    db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource40.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCClient.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ServerSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientJDBCObjectFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientJDBCObjectFactory.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientJDBCObjectFactory.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientJDBCObjectFactory.java Sat Apr 21 17:08:27 2007
@@ -22,6 +22,7 @@
 package org.apache.derby.client.am;
 
 import org.apache.derby.client.ClientPooledConnection;
+import org.apache.derby.client.ClientXAConnection;
 import org.apache.derby.jdbc.ClientDataSource;
 import java.sql.SQLException;
 import org.apache.derby.jdbc.ClientBaseDataSource;
@@ -52,6 +53,15 @@
      */
     ClientPooledConnection newClientPooledConnection(ClientBaseDataSource ds,
             LogWriter logWriter,String user,String password,int rmId)
+            throws SQLException;
+    
+    /**
+     * This method is used to return an instance of
+     * ClientXAConnection (or ClientXAConnection40) class which
+     * implements javax.sql.XAConnection
+     */
+    ClientXAConnection newClientXAConnection(ClientBaseDataSource ds,
+            LogWriter logWriter,String user,String password)
             throws SQLException;
     
     /**

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl.java Sat Apr 21 17:08:27 2007
@@ -25,6 +25,7 @@
 import java.sql.Connection;
 import java.sql.SQLException;
 import org.apache.derby.client.ClientPooledConnection;
+import org.apache.derby.client.ClientXAConnection;
 import org.apache.derby.client.am.CallableStatement;
 import org.apache.derby.client.am.ClientJDBCObjectFactory;
 import org.apache.derby.client.am.LogicalConnection;
@@ -37,7 +38,9 @@
 import org.apache.derby.client.am.Statement;
 import org.apache.derby.client.am.SqlException;
 import org.apache.derby.client.am.Cursor;
+import org.apache.derby.client.net.NetLogWriter;
 import org.apache.derby.jdbc.ClientBaseDataSource;
+import org.apache.derby.jdbc.ClientXADataSource;
 import org.apache.derby.client.am.ColumnMetaData;
 
 /**
@@ -63,6 +66,15 @@
             LogWriter logWriter,String user,
             String password,int rmId) throws SQLException {
         return new ClientPooledConnection(ds,logWriter,user,password,rmId);
+    }
+    /**
+     * Returns an instance of org.apache.derby.client.ClientXAConnection 
+     */
+    public ClientXAConnection newClientXAConnection(ClientBaseDataSource ds,
+        LogWriter logWriter,String user, String password) throws SQLException
+    {
+        return new ClientXAConnection((ClientXADataSource)ds,
+            (NetLogWriter)logWriter,user,password);
     }
     /**
      * Returns an instance of org.apache.derby.client.am.CallableStatement.

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl40.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/ClientJDBCObjectFactoryImpl40.java Sat Apr 21 17:08:27 2007
@@ -23,6 +23,8 @@
 
 import org.apache.derby.client.ClientPooledConnection;
 import org.apache.derby.client.ClientPooledConnection40;
+import org.apache.derby.client.ClientXAConnection;
+import org.apache.derby.client.ClientXAConnection40;
 import org.apache.derby.client.am.CallableStatement;
 import org.apache.derby.client.am.CallableStatement40;
 import org.apache.derby.client.am.ColumnMetaData;
@@ -42,9 +44,12 @@
 import org.apache.derby.client.am.Statement40;
 import org.apache.derby.client.am.SqlException;
 import org.apache.derby.client.am.Cursor;
+import org.apache.derby.client.net.NetLogWriter;
 import org.apache.derby.jdbc.ClientDataSource;
-import java.sql.SQLException;
 import org.apache.derby.jdbc.ClientBaseDataSource;
+import org.apache.derby.jdbc.ClientXADataSource;
+
+import java.sql.SQLException;
 
 /**
  * Implements the ClientJDBCObjectFactory interface
@@ -74,6 +79,16 @@
             ClientBaseDataSource ds, LogWriter logWriter,String user,
             String password,int rmId) throws SQLException {
         return new ClientPooledConnection40(ds,logWriter,user,password,rmId);
+    }
+    /**
+     * Returns an instance of org.apache.derby.client.ClientXAConnection40 
+     */
+    public ClientXAConnection newClientXAConnection(
+        ClientBaseDataSource ds, LogWriter logWriter,String user,
+        String password) throws SQLException
+    {
+        return new ClientXAConnection40((ClientXADataSource)ds,
+            (NetLogWriter)logWriter,user,password);
     }
     /**
      * Returns an instance of org.apache.derby.client.am.CallableStatement.

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource.java Sat Apr 21 17:08:27 2007
@@ -28,6 +28,7 @@
 
 import org.apache.derby.client.ClientXAConnection;
 import org.apache.derby.client.net.NetLogWriter;
+import org.apache.derby.client.am.LogWriter;
 import org.apache.derby.client.am.SqlException;
 
 
@@ -68,11 +69,23 @@
         try
         {
             NetLogWriter dncLogWriter = (NetLogWriter) super.computeDncLogWriterForNewConnection("_xads");
-            return new ClientXAConnection(this, dncLogWriter, user, password);
+            return getXAConnectionX(dncLogWriter, this, user, password);
         }
         catch ( SqlException se )
         {
             throw se.getSQLException();
         }
     }    
+
+    /**
+     * Method that establishes the initial physical connection
+     * using DS properties instead of CPDS properties.
+     */
+    private XAConnection getXAConnectionX(LogWriter dncLogWriter,
+        ClientBaseDataSource ds, String user, String password)
+        throws SQLException
+    {
+        return ClientDriver.getFactory().newClientXAConnection(ds,
+                dncLogWriter, user, password);
+    }   
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource40.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource40.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientXADataSource40.java Sat Apr 21 17:08:27 2007
@@ -52,22 +52,6 @@
  */
 public class ClientXADataSource40 extends ClientXADataSource {
     
-    /**
-     * creates a jdbc4.0 XAConnection
-     * @param user 
-     * @param password 
-     * @return XAConnection
-     */
-    public XAConnection getXAConnection(String user, String password) throws SQLException {
-        try {
-            NetLogWriter dncLogWriter = (NetLogWriter) 
-                        super.computeDncLogWriterForNewConnection("_xads");
-            return new ClientXAConnection40 (this, dncLogWriter, user, password);
-        } catch ( SqlException se ) {
-            throw se.getSQLException();
-        }
-    }
-    
 	/**
      * Returns false unless <code>interfaces</code> is implemented 
      * 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver30.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver30.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver30.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver30.java Sat Apr 21 17:08:27 2007
@@ -30,10 +30,16 @@
 import org.apache.derby.iapi.jdbc.BrokeredConnection;
 import org.apache.derby.iapi.jdbc.BrokeredConnection30;
 import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;
+import org.apache.derby.iapi.jdbc.ResourceAdapter;
+
 import java.sql.Connection;
 import java.sql.SQLException;
 import org.apache.derby.impl.jdbc.*;
 
+/** -- jdbc 2.0. extension -- */
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
+
 import java.util.Properties;
 
 /**
@@ -123,4 +129,30 @@
 
 		return new BrokeredConnection30(control);
 	}
+
+    /**
+     * Create and return an EmbedPooledConnection from the received instance
+     * of EmbeddedDataSource.
+     */
+    protected PooledConnection getNewPooledConnection(
+        EmbeddedDataSource eds, String user, String password,
+        boolean requestPassword) throws SQLException
+    {
+        return new EmbedPooledConnection(
+            eds, user, password, requestPassword);
+    }
+
+    /**
+     * Create and return an EmbedXAConnection from the received instance
+     * of EmbeddedDataSource.
+     */
+    protected XAConnection getNewXAConnection(
+        EmbeddedDataSource eds, ResourceAdapter ra,
+        String user, String password, boolean requestPassword)
+        throws SQLException
+    {
+        return new EmbedXAConnection(
+            eds, ra, user, password, requestPassword);
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver40.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/Driver40.java Sat Apr 21 17:08:27 2007
@@ -39,6 +39,7 @@
 import org.apache.derby.impl.jdbc.SQLExceptionFactory40;
 import org.apache.derby.impl.jdbc.EmbedStatement40;
 import org.apache.derby.impl.jdbc.EmbedResultSetMetaData40;
+import org.apache.derby.iapi.jdbc.ResourceAdapter;
 import org.apache.derby.impl.jdbc.Util;
 import java.sql.Connection;
 import java.sql.SQLException;
@@ -47,6 +48,9 @@
 import java.util.Properties;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
 
+/** -- jdbc 2.0. extension -- */
+import javax.sql.PooledConnection;
+import javax.sql.XAConnection;
 
 public class Driver40 extends Driver30 {
     
@@ -160,4 +164,29 @@
                              (ResultColumnDescriptor[] columnInfo) {
             return new EmbedResultSetMetaData40(columnInfo);
         }
+
+    /**
+     * Create and return an EmbedPooledConnection from the received instance
+     * of EmbeddedDataSource.
+     */
+    protected PooledConnection getNewPooledConnection(
+        EmbeddedDataSource eds, String user, String password,
+        boolean requestPassword) throws SQLException
+    {
+        return new EmbedPooledConnection40(
+            eds, user, password, requestPassword);
+    }
+
+    /**
+     * Create and return an EmbedXAConnection from the received instance
+     * of EmbeddedDataSource.
+     */
+    protected XAConnection getNewXAConnection(
+        EmbeddedDataSource eds, ResourceAdapter ra,
+        String user, String password, boolean requestPassword)
+        throws SQLException
+    {
+        return new EmbedXAConnection40(
+            eds, ra, user, password, requestPassword);
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource.java Sat Apr 21 17:08:27 2007
@@ -94,12 +94,43 @@
 	}
         
     /**
-     * create and returns EmbedPooledConnection.
+     * Create and return an EmbedPooledConnection from this instance
+     * of EmbeddedConnectionPoolDataSource.
      */
     protected PooledConnection createPooledConnection (String user,
-            String password, boolean requestPassword) throws SQLException {
-        return new EmbedPooledConnection(this, user, password, requestPassword);
+        String password, boolean requestPassword) throws SQLException
+    {
+        /* This object (EmbeddedConnectionPoolDataSource) is a JDBC 2
+         * and JDBC 3 implementation of ConnectionPoolDatSource.  However,
+         * it's possible that we are running with a newer driver (esp.
+         * JDBC 4) in which case we should return a PooledConnection that
+         * implements the newer JDBC interfaces--even if "this" object
+         * does not itself satisfy those interfaces.  As an example, if
+         * we have a JDK 6 application then even though this specific
+         * object doesn't implement JDBC 4 (it only implements JDBC 2
+         * and 3), we should still return a PooledConnection object that
+         * *does* implement JDBC 4 because that's what a JDK 6 app
+         * expects.
+         *
+         * By calling "findDriver()" here we will get the appropriate
+         * driver for the JDK in use (ex. if using JDK 6 then findDriver()
+         * will return the JDBC 4 driver).  If we then ask the driver to
+         * give us a pooled connection, we will get a connection that
+         * corresponds to whatever driver/JDBC implementation is being
+         * used--which is what we want.  So for a JDK 6 application we
+         * will correctly return a JDBC 4 PooledConnection. DERBY-2488.
+         *
+         * This type of scenario can occur if an application that was
+         * previously running with an older JVM (ex. JDK 1.4/1.5) starts
+         * running with a newer JVM (ex. JDK 6), in which case the app
+         * is probably still using the "old" data source (ex. is still
+         * instantiating EmbeddedConnectionPoolDataSource) instead of
+         * the newer one (EmbeddedConnectionPoolDataSource40).
+         */
+        return ((Driver30) findDriver()).getNewPooledConnection(
+            this, user, password, requestPassword);
     }
+
 }
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource40.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedConnectionPoolDataSource40.java Sat Apr 21 17:08:27 2007
@@ -91,14 +91,4 @@
                     interfaces);
         }
     }
-
-    /**
-     * create and returns EmbedPooledConnection.
-     */
-    protected PooledConnection createPooledConnection (String user, 
-            String password, boolean requestPassword)  throws SQLException {
-        return new EmbedPooledConnection40(this, user, password,
-                                           requestPassword);
-    }    
-        
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource.java Sat Apr 21 17:08:27 2007
@@ -191,15 +191,45 @@
 	}
         
     /**
-     * Intantiate and returns EmbedXAConnection.
+     * Intantiate and return an EmbedXAConnection from this instance
+     * of EmbeddedXADataSource.
+     *
      * @param user 
      * @param password 
      * @return XAConnection
      */
-        protected XAConnection createXAConnection (ResourceAdapter ra, 
-                String user, String password, 
-                boolean requestPassword) throws SQLException {
-            return new EmbedXAConnection(this, ra, user, 
-                    password, requestPassword);
-        }
+    protected XAConnection createXAConnection (ResourceAdapter ra, 
+        String user, String password, boolean requestPassword)
+        throws SQLException
+    {
+        /* This object (EmbeddedXADataSource) is a JDBC 2 and JDBC 3
+         * implementation of XADatSource.  However, it's possible that we
+         * are running with a newer driver (esp. JDBC 4) in which case we
+         * should return a PooledConnection that implements the newer JDBC
+         * interfaces--even if "this" object does not itself satisfy those
+         * interfaces.  As an example, if we have a JDK 6 application then
+         * even though this specific object doesn't implement JDBC 4 (it
+         * only implements JDBC 2 and 3), we should still return an
+         * XAConnection object that *does* implement JDBC 4 because that's
+         * what a JDK 6 app expects.
+         *
+         * By calling "findDriver()" here we will get the appropriate
+         * driver for the JDK in use (ex. if using JDK 6 then findDriver()
+         * will return the JDBC 4 driver).  If we then ask the driver to
+         * give us an XA connection, we will get a connection that
+         * corresponds to whatever driver/JDBC implementation is being
+         * used--which is what we want.  So for a JDK 6 application we
+         * will correctly return a JDBC 4 XAConnection. DERBY-2488.
+         *
+         * This type of scenario can occur if an application that was
+         * previously running with an older JVM (ex. JDK 1.4/1.5) starts
+         * running with a newer JVM (ex. JDK 6), in which case the app
+         * is probably still using the "old" data source (ex. is still
+         * instantiating EmbeddedXADataSource) instead of the newer one
+         * (EmbeddedXADataSource40).
+         */
+        return ((Driver30) findDriver()).getNewXAConnection(
+            this, ra, user, password, requestPassword);
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource40.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource40.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource40.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbeddedXADataSource40.java Sat Apr 21 17:08:27 2007
@@ -100,16 +100,4 @@
         }
     }
 	
-    /**
-     * Intantiate and returns EmbedXAConnection.
-     * @param user 
-     * @param password 
-     * @return XAConnection
-     */
-        protected XAConnection createXAConnection (ResourceAdapter ra, 
-                String user, String password,
-                boolean requestPassword)  throws SQLException {
-            return new EmbedXAConnection40 (this, ra, user, 
-                    password, requestPassword);
-        }
 }

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/JDBC4FromJDBC3DataSourceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/JDBC4FromJDBC3DataSourceTest.java?view=auto&rev=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/JDBC4FromJDBC3DataSourceTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/JDBC4FromJDBC3DataSourceTest.java Sat Apr 21 17:08:27 2007
@@ -0,0 +1,155 @@
+/*
+ 
+   Derby - Class org.apache.derbyTesting.functionTests.tests.jdbc4.JDBC4FromJDBC3DataSourceTest
+
+   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.derbyTesting.functionTests.tests.jdbc4;
+
+import junit.framework.*;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.JDBCClient;
+import org.apache.derbyTesting.junit.JDBCDataSource;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.sql.ConnectionPoolDataSource;
+import javax.sql.DataSource;
+import javax.sql.PooledConnection;
+import javax.sql.StatementEvent;
+import javax.sql.StatementEventListener;
+import javax.sql.XADataSource;
+
+/**
+ * This test ensures that when a JDBC 4 application instantiates a JDBC 3
+ * data source, that data source will return JDBC 4 connections even though
+ * the data source itself is not a JDBC 4 object.
+ */
+public class JDBC4FromJDBC3DataSourceTest extends BaseJDBCTestCase {
+    
+    /**
+     * Create a test with the given name.
+     * @param name name of the test.
+     *
+     */
+    public JDBC4FromJDBC3DataSourceTest(String name)
+    {
+        super(name);
+    }
+    
+    /**
+     * Return suite with all tests of the class.
+     */
+    public static Test suite()
+    {
+        // Only run this test if we have a JDBC 4 JVM.
+        if (JDBC.vmSupportsJDBC4())
+        {
+            return TestConfiguration.forceJDBC3Suite(
+                JDBC4FromJDBC3DataSourceTest.class);
+        }
+
+        // Else return empty suite.
+        return new TestSuite("JDBC 4 from JDBC 3 Data Sources");
+    }
+
+    /**
+     * Test that a JDBC 3 data source returns a JDBC 4 PooledConnection
+     * when running with a JDBC 4 JDK.
+     */
+    public void testPooledConnection() throws Exception
+    {
+        ConnectionPoolDataSource ds = (ConnectionPoolDataSource)
+            JDBCDataSource.getConnectionPoolDataSource();
+
+        assertNonJDBC4DataSource((DataSource)ds);
+        checkJDBC4Interface(ds.getPooledConnection());
+    }
+
+    /**
+     * Test that a JDBC 3 data source returns a JDBC 4 XAConnection
+     * when running with a JDBC 4 JDK.
+     */
+    public void testXAConnection() throws Exception
+    {
+        XADataSource ds = 
+            (XADataSource) JDBCDataSource.getXADataSource();
+
+        assertNonJDBC4DataSource((DataSource)ds);
+        checkJDBC4Interface(ds.getXAConnection());
+    }
+
+    /**
+     * Make sure that the received DataSource is *not* a JDBC 4
+     * data source, since that would defeat the whole purpose
+     * of this test.
+     */
+    private void assertNonJDBC4DataSource(DataSource ds)
+        throws SQLException
+    {
+        /* Simplest way is to try to call a JDBC 4 interface method;
+         * if it succeeds, then we must have a JDBC 4 data source
+         * (which we don't want).
+         */
+        try {
+
+            ds.isWrapperFor(DataSource.class);
+            fail("Found JDBC 4 data source when JDBC 3 was expected.");
+
+        } catch (java.lang.AbstractMethodError ame) {}
+    }
+
+    /**
+     * Make sure that the received PooledConnection, which we assume came
+     * from a JDBC 3 data source, is nonetheless a JDBC 4 object.
+     */
+    private void checkJDBC4Interface(PooledConnection pc)
+        throws Exception
+    {
+        // Create dummy event listener.
+        StatementEventListener listener =
+            new StatementEventListener()
+            {
+                public void statementClosed(StatementEvent event) {}
+                public void statementErrorOccurred(StatementEvent event) {}
+            };
+
+        /* Assert that metadata reports JDBC 4 for the connection, which
+         * it should even though the connection was created from a JDBC 3
+         * datasource.
+         */
+        Connection conn = pc.getConnection();
+        assertEquals(4, conn.getMetaData().getJDBCMajorVersion());
+        conn.close();
+        conn = null;
+
+        /* The way we check to see if we actually have JDBC 4 objects is
+         * to call two methods that only exist in JDBC 4.  These should
+         * succeed.  Before DERBY-2488 they would fail with an Abstract
+         * MethodError.
+         */
+        pc.addStatementEventListener(listener);
+        pc.removeStatementEventListener(listener);
+        pc.close();
+    }
+
+}

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

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java Sat Apr 21 17:08:27 2007
@@ -70,6 +70,7 @@
         suite.addTest(VerifySignatures.suite());
         suite.addTest (LobStreamTest.suite());
         suite.addTest (BlobSetMethodsTest.suite());
+        suite.addTest (JDBC4FromJDBC3DataSourceTest.suite());
 		
 		return suite;
 	}

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCClient.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCClient.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCClient.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCClient.java Sat Apr 21 17:08:27 2007
@@ -94,6 +94,14 @@
             "org.apache.derby.jdbc.ClientXADataSource",
             "jdbc:derby://");
     
+    static final JDBCClient DERBYNETCLIENT_30 = new JDBCClient(
+            "DerbyNetClient",
+            "org.apache.derby.jdbc.ClientDriver",
+            "org.apache.derby.jdbc.ClientDataSource",
+            "org.apache.derby.jdbc.ClientConnectionPoolDataSource",
+            "org.apache.derby.jdbc.ClientXADataSource",
+            "jdbc:derby://");
+
     /**
      * The DB2 Universal JDBC network client.
      * AKA: JCC or DerbyNet.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java Sat Apr 21 17:08:27 2007
@@ -44,6 +44,33 @@
     }
     
     /**
+     * Return a ConnectionPoolDataSource corresponding to the current
+     * configuration.  This method returns a generic Object (as opposed
+     * to a ConnectionPoolDataSource) because this class has to work
+     * with JSR169 JVMs, as well, and those JVMs do not include the
+     * javax.sql.ConnectionPoolDataSource class.
+     */
+    public static Object getConnectionPoolDataSource()
+    {
+        TestConfiguration config = TestConfiguration.getCurrent();
+        return getDataSource(config, (HashMap) null,
+			config.getJDBCClient().getConnectionPoolDataSourceClassName());
+    }
+    
+    /*
+     * Return an XADataSource corresponding to the current configuration.
+     * This method returns a generic Object (as opposed to an XADataSource)
+     * because this class has to work with JSR169 JVMs, as well, and those
+     * JVMs do not include the javax.sql.XADataSource class.
+     */
+    public static Object getXADataSource()
+    {
+        TestConfiguration config = TestConfiguration.getCurrent();
+        return getDataSource(config, (HashMap) null,
+            config.getJDBCClient().getXADataSourceClassName());
+    }
+    
+    /**
      * Return a DataSource corresponding to the current
      * configuration except that the databse name is different.
      */
@@ -86,13 +113,23 @@
     static javax.sql.DataSource getDataSource(TestConfiguration config,
             HashMap beanProperties)
     {
+        return (javax.sql.DataSource) getDataSource(config,
+            beanProperties, config.getJDBCClient().getDataSourceClassName());
+    }
+
+    /**
+     * Create a new DataSource object setup from the passed in
+     * TestConfiguration using the received properties and data
+     * source class name.
+     */
+    static Object getDataSource(TestConfiguration config,
+        HashMap beanProperties, String dsClassName)
+    {
         if (beanProperties == null)
              beanProperties = getDataSourceProperties(config);
         
-        String dataSourceClass = config.getJDBCClient().getDataSourceClassName();
-        
-        return (javax.sql.DataSource) getDataSourceObject(dataSourceClass,
-                beanProperties);
+        return (javax.sql.DataSource) getDataSourceObject(dsClassName,
+            beanProperties);
     }
     
     /**

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ServerSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ServerSetup.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ServerSetup.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ServerSetup.java Sat Apr 21 17:08:27 2007
@@ -32,6 +32,7 @@
 
     private final String host;
     private final int port;
+    private JDBCClient client;
     
     public ServerSetup(Test test, String host, int port) {
         super(test);
@@ -41,7 +42,15 @@
 
     TestConfiguration getNewConfiguration(TestConfiguration old) {
                
-        return new TestConfiguration(old, JDBCClient.DERBYNETCLIENT,
-                    host, port);
+        return new TestConfiguration(old,
+            (client == null) ? JDBCClient.DERBYNETCLIENT : client, host, port);
+    }
+
+    /**
+     * Specify a JDBCClient to use in place of the default DERBYNETCLIENT.
+     */
+    void setJDBCClient(JDBCClient newClient)
+    {
+        this.client = newClient;
     }
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java?view=diff&rev=531129&r1=531128&r2=531129
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java Sat Apr 21 17:08:27 2007
@@ -227,7 +227,31 @@
 
         return (suite);
     }
-    
+
+    /**
+     * Return a Test suite that contains all the test fixtures
+     * for the passed in class running in embedded and client-
+     * server *JDBC3* configurations.
+     * <BR>
+     * Each set of embedded and set of client server tests is
+     * decorated with a CleanDatabaseTestSetup.
+     * <BR>
+     */
+    public static Test forceJDBC3Suite(Class testClass)
+    {
+        final TestSuite suite = new TestSuite(suiteName(testClass));
+
+        suite.addTest(
+            new CleanDatabaseTestSetup(
+                forceJDBC3Embedded(embeddedSuite(testClass))));
+
+        suite.addTest(
+            new CleanDatabaseTestSetup(
+                forceJDBC3NetClient(clientServerSuite(testClass))));
+
+        return (suite);
+    }
+
     /**
      * Generate a suite name from a class name, taking
      * only the last element of the fully qualified class name.
@@ -567,6 +591,26 @@
         if (JDBC.vmSupportsJDBC4()) {
             test = new JDBCClientSetup(test, JDBCClient.EMBEDDED_30);
         }
+        return test;
+    }
+    
+    /**
+     * Returns a decorator that forces the JDBC 3 network client in
+     * a Java SE 6/JDBC 4 environment. The only difference is that
+     * the DataSource class names will be the "old" JDBC 3 versions
+     * and not the JDBC 4 specific ones.
+     *
+     * Assumption is that the received Test is an instance of ServerSetup,
+     * which is the decorator for client server tests.  If that is not
+     * the case then this method is a no-op.
+     *
+     * @param test Test around which to wrap the JDBC 3 network client
+     *  configuration.
+     */
+    public static Test forceJDBC3NetClient(Test test)
+    {
+        if (JDBC.vmSupportsJDBC4() && (test instanceof ServerSetup))
+            ((ServerSetup)test).setJDBCClient(JDBCClient.DERBYNETCLIENT_30);
         return test;
     }