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 rh...@apache.org on 2018/01/23 01:00:24 UTC

svn commit: r1821953 - in /db/derby/code/trunk: ./ java/build/org/apache/derbyBuild/lastgoodjarcontents/ java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/client/net/ java/client/org/apache/derby/...

Author: rhillegas
Date: Tue Jan 23 01:00:23 2018
New Revision: 1821953

URL: http://svn.apache.org/viewvc?rev=1821953&view=rev
Log:
DERBY-6945: Move the autoloaded client driver out of the public api package and into a package internal to derbyclient.jar; commit derby-6945-13-aa-create-ClientAutoloadedDriver.diff.

Added:
    db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java   (with props)
Modified:
    db/derby/code/trunk/build.xml
    db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/insane.derbyclient.jar.lastcontents
    db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/sane.derbyclient.jar.lastcontents
    db/derby/code/trunk/java/client/org/apache/derby/client/BasicClientDataSource.java
    db/derby/code/trunk/java/client/org/apache/derby/client/ClientPooledConnection.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientPreparedStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCacheInteractor.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCallableStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetPreparedStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java
    db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Driver.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/AutoloadTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DriverTest.java

Modified: db/derby/code/trunk/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/build.xml?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/build.xml (original)
+++ db/derby/code/trunk/build.xml Tue Jan 23 01:00:23 2018
@@ -1665,7 +1665,7 @@
 
     <!-- declare the client driver for autoloading by the JDBC 4 DriverManager -->
     <antcall target="declare-autoloadable-driver">
-      <param name="driver.name" value="org.apache.derby.jdbc.ClientDriver"/>
+      <param name="driver.name" value="org.apache.derby.client.ClientAutoloadedDriver"/>
     </antcall>
 
     <delete file="${derby.jar.dir}/derbyclient.jar"/>

Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/insane.derbyclient.jar.lastcontents
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/insane.derbyclient.jar.lastcontents?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/insane.derbyclient.jar.lastcontents (original)
+++ db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/insane.derbyclient.jar.lastcontents Tue Jan 23 01:00:23 2018
@@ -1,4 +1,5 @@
 org.apache.derby.client.BasicClientDataSource.class
+org.apache.derby.client.ClientAutoloadedDriver.class
 org.apache.derby.client.ClientDataSourceFactory.class
 org.apache.derby.client.ClientDataSourceInterface.class
 org.apache.derby.client.ClientPooledConnection.class

Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/sane.derbyclient.jar.lastcontents
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/sane.derbyclient.jar.lastcontents?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/sane.derbyclient.jar.lastcontents (original)
+++ db/derby/code/trunk/java/build/org/apache/derbyBuild/lastgoodjarcontents/sane.derbyclient.jar.lastcontents Tue Jan 23 01:00:23 2018
@@ -1,4 +1,5 @@
 org.apache.derby.client.BasicClientDataSource.class
+org.apache.derby.client.ClientAutoloadedDriver.class
 org.apache.derby.client.ClientDataSourceFactory.class
 org.apache.derby.client.ClientDataSourceInterface.class
 org.apache.derby.client.ClientPooledConnection.class

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/BasicClientDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/BasicClientDataSource.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/BasicClientDataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/BasicClientDataSource.java Tue Jan 23 01:00:23 2018
@@ -55,7 +55,6 @@ import org.apache.derby.client.net.NetLo
 import org.apache.derby.shared.common.error.ExceptionUtil;
 import org.apache.derby.shared.common.reference.Attribute;
 import org.apache.derby.shared.common.reference.SQLState;
-import org.apache.derby.jdbc.ClientDriver;
 
 /**
  * This data source is suitable for client/server use of Derby,
@@ -897,7 +896,7 @@ public class BasicClientDataSource
     }
 
     // tokenize "property=value;property=value..." and returns new properties
-    //object This method is used both by ClientDriver to parse the url and
+    //object This method is used both by ClientAutoloadedDriver to parse the url and
     //ClientDataSource.setConnectionAttributes
     public static Properties tokenizeAttributes(
         String attributeString, Properties properties) throws SqlException {
@@ -1477,7 +1476,7 @@ public class BasicClientDataSource
     private Connection getConnectionX(LogWriter dncLogWriter,
                                       String user, String password)
             throws SqlException {
-        return ClientDriver.getFactory().newNetConnection(
+        return ClientAutoloadedDriver.getFactory().newNetConnection(
                 dncLogWriter, user, password, this, -1, false);
 
     }
@@ -1601,7 +1600,7 @@ public class BasicClientDataSource
             String user,
             String password) throws SQLException {
 
-            return ClientDriver.getFactory().newClientPooledConnection(ds,
+            return ClientAutoloadedDriver.getFactory().newClientPooledConnection(ds,
                     dncLogWriter, user, password);
     }
 
@@ -1649,7 +1648,7 @@ public class BasicClientDataSource
         BasicClientDataSource ds, String user, String password)
         throws SQLException
     {
-        return ClientDriver.getFactory().newClientXAConnection(ds,
+        return ClientAutoloadedDriver.getFactory().newClientXAConnection(ds,
                 dncLogWriter, user, password);
     }
 

Added: db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java?rev=1821953&view=auto
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java (added)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java Tue Jan 23 01:00:23 2018
@@ -0,0 +1,520 @@
+/*
+
+   Derby - Class org.apache.derby.client.ClientAutoloadedDriver
+
+   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.derby.client;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.logging.Logger;
+import org.apache.derby.client.am.Configuration;
+import org.apache.derby.client.am.SqlException;
+import org.apache.derby.client.am.Utils;
+import org.apache.derby.client.am.Version;
+import org.apache.derby.client.am.ClientJDBCObjectFactory;
+import org.apache.derby.client.am.ClientMessageId;
+import org.apache.derby.client.am.LogWriter;
+import org.apache.derby.client.net.ClientJDBCObjectFactoryImpl;
+import org.apache.derby.client.net.NetConnection;
+import org.apache.derby.shared.common.reference.Attribute;
+import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.shared.common.reference.MessageId;
+
+/**
+ * The client JDBC driver (type 4) for Derby.
+ */
+public class ClientAutoloadedDriver implements Driver
+{
+    private transient int traceFileSuffixIndex_ = 0;
+
+    private final static int DERBY_REMOTE_PROTOCOL = 1;
+    
+    private static ClientJDBCObjectFactory factoryObject = null;
+
+    static private SQLException exceptionsOnLoadDriver__ = null;
+    // Keep track of the registere driver so that we can deregister it if we're a stored proc.
+    static private ClientAutoloadedDriver registeredDriver__ = null;
+
+    static
+    {
+        registerMe(new ClientAutoloadedDriver());
+    }
+
+    protected static void   registerMe( ClientAutoloadedDriver me )
+    {
+        // The Configuration static clause should execute before the following line does.
+        SqlException ole = Configuration.getExceptionOnLoadResources();
+        
+        if (ole != null) {
+            SQLException e = ole.getSQLException();
+            exceptionsOnLoadDriver__ =
+                Utils.accumulateSQLException(e, exceptionsOnLoadDriver__);
+        }
+        
+        try {
+            registeredDriver__ = me;
+            DriverManager.registerDriver(registeredDriver__);
+        } catch (SQLException e) {
+            // A null log writer is passed, because jdbc 1 sql exceptions are automatically traced
+            exceptionsOnLoadDriver__ =
+                    new SqlException(null, 
+                        new ClientMessageId(SQLState.JDBC_DRIVER_REGISTER)).getSQLException();
+            exceptionsOnLoadDriver__.setNextException(e);
+        }
+    }
+
+    public ClientAutoloadedDriver() {
+    }
+
+    public Connection connect(String url,
+                              Properties properties) throws SQLException {
+        NetConnection conn;
+        
+        checkURLNotNull( url );
+
+        try {    
+            if (exceptionsOnLoadDriver__ != null) {
+                throw exceptionsOnLoadDriver__;
+            }
+
+            if (properties == null) {
+                properties = new Properties();
+            }
+
+            StringTokenizer urlTokenizer =
+                    new StringTokenizer(url, "/:= \t\n\r\f", true);
+
+            int protocol = tokenizeProtocol(url, urlTokenizer);
+            if (protocol == 0) {
+                return null; // unrecognized database URL prefix.
+            }
+
+            String slashOrNull = null;
+            if (protocol == DERBY_REMOTE_PROTOCOL) {
+                try {
+                    slashOrNull = urlTokenizer.nextToken(":/");
+                } catch (NoSuchElementException e) {
+                    // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+                    throw new SqlException(null, 
+                        new ClientMessageId(SQLState.MALFORMED_URL),
+                        e, url);
+                }
+            }
+            String server = tokenizeServerName(urlTokenizer, url);    // "/server"
+            int port = tokenizeOptionalPortNumber(urlTokenizer, url); // "[:port]/"
+            if (port == 0) {
+                port = BasicClientDataSource.propertyDefault_portNumber;
+            }
+
+            // database is the database name and attributes.  This will be
+            // sent to network server as the databaseName
+            String database = tokenizeDatabase(urlTokenizer, url); // "database"
+            Properties augmentedProperties =
+                tokenizeURLProperties(url, properties);
+            database = appendDatabaseAttributes(database,augmentedProperties);
+
+            int traceLevel;
+            try {
+                traceLevel =
+                    BasicClientDataSource.getTraceLevel(augmentedProperties);
+            } catch (NumberFormatException e) {
+                // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+                throw new SqlException(null, 
+                    new ClientMessageId(SQLState.TRACELEVEL_FORMAT_INVALID), e);
+            }
+
+            // Jdbc 1 connections will write driver trace info on a
+            // driver-wide basis using the jdbc 1 driver manager log writer.
+            // This log writer may be narrowed to the connection-level
+            // This log writer will be passed to the agent constructor.
+            LogWriter dncLogWriter =
+                BasicClientDataSource.computeDncLogWriterForNewConnection(
+                    DriverManager.getLogWriter(),
+                    BasicClientDataSource.getTraceDirectory(
+                        augmentedProperties),
+                    BasicClientDataSource.getTraceFile(
+                        augmentedProperties),
+                    BasicClientDataSource.getTraceFileAppend(
+                        augmentedProperties),
+                    traceLevel,
+                    "_driver",
+                    traceFileSuffixIndex_++);
+            
+            
+            conn = (NetConnection)getFactory().
+                    newNetConnection(dncLogWriter,
+                    DriverManager.getLoginTimeout(),
+                    server,
+                    port,
+                    database,
+                    augmentedProperties);
+        } catch(SqlException se) {
+            throw se.getSQLException();
+        }
+        
+        if(conn.isConnectionNull())
+            return null;
+        
+        return conn;
+    }
+
+    /**
+     * Append attributes to the database name except for user/password 
+     * which are sent as part of the protocol, and SSL which is used 
+     * locally in the client.
+     * Other attributes will  be sent to the server with the database name
+     * Assumes augmentedProperties is not null
+     * 
+     * @param database - Short database name
+     * @param augmentedProperties - Set of properties to append as attributes
+     * @return databaseName + attributes (e.g. mydb;create=true) 
+     */
+    private String appendDatabaseAttributes(String database, Properties augmentedProperties) {
+    
+        StringBuffer longDatabase = new StringBuffer(database);
+        for (Enumeration keys = augmentedProperties.propertyNames();
+             keys.hasMoreElements() ;)
+        {
+            String key = (String) keys.nextElement();
+            if (key.equals(Attribute.USERNAME_ATTR) || 
+                key.equals(Attribute.PASSWORD_ATTR) ||
+                key.equals(Attribute.SSL_ATTR))
+                continue;
+            longDatabase.append(";" + key + "=" + augmentedProperties.getProperty(key));
+        }
+        return longDatabase.toString();
+    }
+
+    public boolean acceptsURL(String url) throws SQLException {
+
+        checkURLNotNull( url );
+        
+        try
+        {
+            StringTokenizer urlTokenizer =
+                    new StringTokenizer(url, "/:=; \t\n\r\f", true);
+            int protocol = tokenizeProtocol(url, urlTokenizer);
+            return protocol != 0;
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+    private void    checkURLNotNull( String url ) throws SQLException
+    {
+        if ( url == null )
+        {
+            throw (new SqlException
+                (
+                 null, 
+                 new ClientMessageId( SQLState.MALFORMED_URL), "null"
+                 )).getSQLException();
+        }
+    }
+
+    public DriverPropertyInfo[] getPropertyInfo(
+            String url,
+            Properties properties) throws SQLException {
+
+        DriverPropertyInfo driverPropertyInfo[] = new DriverPropertyInfo[2];
+
+        // If there are no properties set already,
+        // then create a dummy properties just to make the calls go thru.
+        if (properties == null) {
+            properties = new Properties();
+        }
+
+        driverPropertyInfo[0] =
+            new DriverPropertyInfo(
+                Attribute.USERNAME_ATTR,
+                properties.getProperty(
+                    Attribute.USERNAME_ATTR,
+                    BasicClientDataSource.propertyDefault_user));
+
+        driverPropertyInfo[1] =
+                new DriverPropertyInfo(Attribute.PASSWORD_ATTR,
+                        properties.getProperty(Attribute.PASSWORD_ATTR));
+
+        driverPropertyInfo[0].description =
+            SqlException.getMessageUtil().getTextMessage(
+                MessageId.CONN_USERNAME_DESCRIPTION);
+        driverPropertyInfo[1].description =
+            SqlException.getMessageUtil().getTextMessage(
+                MessageId.CONN_PASSWORD_DESCRIPTION);
+
+        driverPropertyInfo[0].required = true;
+        driverPropertyInfo[1].required = false; // depending on the security mechanism
+
+        return driverPropertyInfo;
+    }
+
+    public int getMajorVersion() {
+        return Version.getMajorVersion();
+    }
+
+    public int getMinorVersion() {
+        return Version.getMinorVersion();
+    }
+
+    public boolean jdbcCompliant() {
+        return Configuration.jdbcCompliant;
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    //
+    // INTRODUCED BY JDBC 4.1 IN JAVA 7
+    //
+    ////////////////////////////////////////////////////////////////////
+
+    public  Logger getParentLogger()
+        throws SQLFeatureNotSupportedException
+    {
+        getFactory();
+        throw (SQLFeatureNotSupportedException)
+            (
+             new SqlException( null, new ClientMessageId(SQLState.NOT_IMPLEMENTED), "getParentLogger" )
+             ).getSQLException();
+    }
+
+    // ----------------helper methods---------------------------------------------
+
+    // Tokenize one of the following:
+    //  "jdbc:derby:"
+    // and return 0 if the protcol is unrecognized
+    // return DERBY_PROTOCOL for "jdbc:derby"
+    private static int tokenizeProtocol(
+            String url,
+            StringTokenizer urlTokenizer) throws SqlException {
+
+        // Is this condition necessary, StringTokenizer constructor may do this for us
+        if (url == null) {
+            return 0;
+        }
+
+        if (urlTokenizer == null) {
+            return 0;
+        }
+
+        try {
+            String jdbc = urlTokenizer.nextToken(":");
+            if (!jdbc.equals("jdbc")) {
+                return 0;
+            }
+            if (!urlTokenizer.nextToken(":").equals(":")) {
+                return 0; // Skip over the first colon in jdbc:derby:
+            }
+            String dbname = urlTokenizer.nextToken(":");
+            int protocol = 0;
+            if (dbname.equals("derby") && (url.indexOf("derby://") != -1)) {
+                // For Derby AS need to check for // since jdbc:derby: is also the
+                // embedded prefix
+                protocol = DERBY_REMOTE_PROTOCOL;
+            } else {
+                return 0;
+            }
+
+            if (!urlTokenizer.nextToken(":").equals(":")) {
+                return 0; // Skip over the second colon in jdbc:derby:
+            }
+
+            return protocol;
+        } catch (NoSuchElementException e) {
+            return 0;
+        }
+    }
+
+    // tokenize "/server" from URL jdbc:derby://server:port/
+    // returns server name
+    private static String tokenizeServerName(StringTokenizer urlTokenizer,
+                                             String url) throws SqlException {
+        try {
+            if (!urlTokenizer.nextToken("/").equals("/"))
+            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+            {
+                throw new SqlException(null, 
+                    new ClientMessageId(SQLState.MALFORMED_URL), url);
+            }
+            return urlTokenizer.nextToken("/:");
+        } catch (NoSuchElementException e) {
+            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+                throw new SqlException(null, 
+                    new ClientMessageId(SQLState.MALFORMED_URL), url);
+        }
+    }
+
+    // tokenize "[:portNumber]/" from URL jdbc:derby://server[:port]/
+    // returns the portNumber or zero if portNumber is not specified.
+    private static int tokenizeOptionalPortNumber(StringTokenizer urlTokenizer,
+                                                  String url) throws SqlException {
+        try {
+            String firstToken = urlTokenizer.nextToken(":/");
+            if (firstToken.equals(":")) {
+                String port = urlTokenizer.nextToken("/");
+                if (!urlTokenizer.nextToken("/").equals("/")) {
+                    // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+                    throw new SqlException(null, 
+                        new ClientMessageId(SQLState.MALFORMED_URL), url);
+                }
+                return Integer.parseInt(port);
+            } else if (firstToken.equals("/")) {
+                return 0;
+            } else {
+                // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+                throw new SqlException(null, 
+                    new ClientMessageId(SQLState.MALFORMED_URL), url);
+            }
+        } catch (NoSuchElementException e) {
+            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+            throw new SqlException(null, 
+                new ClientMessageId(SQLState.MALFORMED_URL), e, url);
+        }
+    }
+
+    //return database name
+    private static String tokenizeDatabase(StringTokenizer urlTokenizer,
+                                           String url) throws SqlException {
+        try {
+            // DERBY-618 - database name can contain spaces in the path
+            String databaseName = urlTokenizer.nextToken("\t\n\r\f;");
+            return databaseName;
+        } catch (NoSuchElementException e) {
+            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
+            throw new SqlException(null, 
+                new ClientMessageId(SQLState.MALFORMED_URL), e, url);
+        }
+    }
+
+    private static Properties tokenizeURLProperties(String url,
+                                                    Properties properties)
+            throws SqlException {
+        String attributeString = null;
+        int attributeIndex = -1;
+
+        if ((url != null) &&
+                ((attributeIndex = url.indexOf(";")) != -1)) {
+            attributeString = url.substring(attributeIndex);
+        }
+
+        return BasicClientDataSource.tokenizeAttributes(
+            attributeString, properties);
+    }
+    
+    /**
+     *This method returns an Implementation
+     *of ClientJDBCObjectFactory depending on
+     *VM under use
+     *Currently it returns either
+     *ClientJDBCObjectFactoryImpl
+     *(or)
+     *ClientJDBCObjectFactoryImpl42
+     */
+    
+    public static ClientJDBCObjectFactory getFactory() {
+        // System.err.println("factoryObject="+factoryObject);
+
+        if(factoryObject!=null)
+            return factoryObject;
+        if (Configuration.supportsJDBC42()) {
+            factoryObject = createJDBC42FactoryImpl();
+        } else {
+            factoryObject = createDefaultFactoryImpl();
+        }
+        return factoryObject;
+    }
+    
+    /**
+     *Returns an instance of the ClientJDBCObjectFactoryImpl class
+     */
+    private static ClientJDBCObjectFactory createDefaultFactoryImpl() {
+        return  new ClientJDBCObjectFactoryImpl();
+    }
+    
+    /**
+     *Returns an instance of the ClientJDBCObjectFactoryImpl40 class
+     *If a ClassNotFoundException occurs then it returns an
+     *instance of ClientJDBCObjectFactoryImpl
+     *
+     *If a future version of JDBC comes then
+     *a similar method would be added say createJDBCXXFactoryImpl
+     *in which if  the class is not found then it would
+     *return the lower version thus having a sort of cascading effect
+     *until it gets a valid instance
+     */
+    
+    private static ClientJDBCObjectFactory createJDBC40FactoryImpl() {
+        final String factoryName =
+                "org.apache.derby.client.net.ClientJDBCObjectFactoryImpl40";
+        try {
+            Class<?> clazz = Class.forName(factoryName);
+            return (ClientJDBCObjectFactory) clazz.getConstructor().newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            return createDefaultFactoryImpl();
+        } catch (InstantiationException ie) {
+            return createDefaultFactoryImpl();
+        } catch (IllegalAccessException iae) {
+            return createDefaultFactoryImpl();
+        } catch (NoSuchMethodException iae) {
+            return createDefaultFactoryImpl();
+        } catch (java.lang.reflect.InvocationTargetException iae) {
+            return createDefaultFactoryImpl();
+        }
+    }
+
+    /**
+     *Returns an instance of the ClientJDBCObjectFactoryImpl42 class
+     *If a ClassNotFoundException occurs then it returns an
+     *instance of the most refined ClientJDBCObjectFactoryImpl possible
+     *
+     *If a future version of JDBC comes then
+     *a similar method would be added say createJDBCXXFactoryImpl
+     *in which if  the class is not found then it would
+     *return the lower version thus having a sort of cascading effect
+     *until it gets a valid instance
+     */
+    
+    private static ClientJDBCObjectFactory createJDBC42FactoryImpl() {
+        final String factoryName =
+                "org.apache.derby.client.net.ClientJDBCObjectFactoryImpl42";
+        try {
+            Class<?> clazz = Class.forName(factoryName);
+            return (ClientJDBCObjectFactory) clazz.getConstructor().newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            return createJDBC40FactoryImpl();
+        } catch (InstantiationException ie) {
+            return createJDBC40FactoryImpl();
+        } catch (IllegalAccessException iae) {
+            return createJDBC40FactoryImpl();
+        } catch (NoSuchMethodException iae) {
+            return createJDBC40FactoryImpl();
+        } catch (java.lang.reflect.InvocationTargetException iae) {
+            return createJDBC40FactoryImpl();
+        }
+    }
+
+}

Propchange: db/derby/code/trunk/java/client/org/apache/derby/client/ClientAutoloadedDriver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/ClientPooledConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/ClientPooledConnection.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/ClientPooledConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/ClientPooledConnection.java Tue Jan 23 01:00:23 2018
@@ -39,7 +39,6 @@ import org.apache.derby.client.am.SqlExc
 import org.apache.derby.client.am.stmtcache.JDBCStatementCache;
 import org.apache.derby.client.net.NetXAConnection;
 import org.apache.derby.shared.common.error.ExceptionSeverity;
-import org.apache.derby.jdbc.ClientDriver;
 import org.apache.derby.shared.common.reference.SQLState;
 
 /**
@@ -128,7 +127,7 @@ public class ClientPooledConnection impl
             //on the listeners
             
             physicalConnection_ =
-            ClientDriver.getFactory().newNetConnection(
+            ClientAutoloadedDriver.getFactory().newNetConnection(
                     logWriter_,
                     user,
                     password,
@@ -325,11 +324,11 @@ public class ClientPooledConnection impl
             logicalConnection_.closeWithoutRecyclingToPool();
         }
         if (this.statementCache == null) {
-            logicalConnection_ = ClientDriver.getFactory().newLogicalConnection(
+            logicalConnection_ = ClientAutoloadedDriver.getFactory().newLogicalConnection(
                                                         physicalConnection_,
                                                         this);
         } else {
-            logicalConnection_ = ClientDriver.getFactory().
+            logicalConnection_ = ClientAutoloadedDriver.getFactory().
                     newCachingLogicalConnection(
                             physicalConnection_, this, statementCache);
         }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java Tue Jan 23 01:00:23 2018
@@ -24,7 +24,7 @@ package org.apache.derby.client.am;
 import java.io.PrintWriter;
 import java.sql.BatchUpdateException;
 import java.sql.Types;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.shared.common.reference.JDBC40Translation;
 import org.apache.derby.shared.common.reference.SQLState;
 
@@ -324,7 +324,7 @@ public abstract class Agent {
             }
         }
         if (accumulatedExceptions != null) {
-            throw ClientDriver.getFactory().newBatchUpdateException(logWriter_,
+            throw ClientAutoloadedDriver.getFactory().newBatchUpdateException(logWriter_,
                 new ClientMessageId(SQLState.BATCH_NON_ATOMIC_FAILURE),
                 null, updateCounts, accumulatedExceptions);
         }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientPreparedStatement.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientPreparedStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ClientPreparedStatement.java Tue Jan 23 01:00:23 2018
@@ -49,7 +49,7 @@ import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Iterator;
 import org.apache.derby.client.ClientPooledConnection;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.shared.common.sanity.SanityManager;
 
@@ -1805,7 +1805,7 @@ public class ClientPreparedStatement ext
     private ClientParameterMetaData getParameterMetaDataX()
             throws SqlException {
         ClientParameterMetaData pm =
-            ClientDriver.getFactory().
+            ClientAutoloadedDriver.getFactory().
             newParameterMetaData(getColumnMetaDataX());
         return pm;
     }
@@ -1815,7 +1815,7 @@ public class ClientPreparedStatement ext
         return 
             parameterMetaData_ != null ?
             parameterMetaData_ : 
-            ClientDriver.getFactory().newColumnMetaData(agent_.logWriter_, 0);
+            ClientAutoloadedDriver.getFactory().newColumnMetaData(agent_.logWriter_, 0);
     }
 
     // ------------------------ box car and callback methods --------------------------------
@@ -2246,7 +2246,7 @@ public class ClientPreparedStatement ext
         // and the values 0 and 0xffff are reserved as special values. So
         // that imposes an upper limit on the batch size we can support:
         if (batchSize > 65534)
-            throw ClientDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
+            throw ClientAutoloadedDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
                 new ClientMessageId(SQLState.TOO_MANY_COMMANDS_FOR_BATCH), 
                 new Object[] { 65534 }, updateCounts, null );
 
@@ -2258,11 +2258,11 @@ public class ClientPreparedStatement ext
         }
 
         if (!supportsQueryBatchRequest && sqlMode_ == isQuery__) {
-            throw ClientDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
+            throw ClientAutoloadedDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
             new ClientMessageId(SQLState.CANNOT_BATCH_QUERIES), (Object [])null, updateCounts, null);
         }
         if (supportsQueryBatchRequest && sqlMode_ != isQuery__) {
-            throw ClientDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
+            throw ClientAutoloadedDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
                 new ClientMessageId(SQLState.QUERY_BATCH_ON_NON_QUERY_STATEMENT), 
                 (Object [])null, updateCounts, null);
         }
@@ -2311,7 +2311,7 @@ public class ClientPreparedStatement ext
                         chainAutoCommit || (i != batchSize - 1));  // more statements to chain
             } else if (outputRegistered_) // make sure no output parameters are registered
             {
-                throw ClientDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
+                throw ClientAutoloadedDriver.getFactory().newBatchUpdateException(agent_.logWriter_, 
                     new ClientMessageId(SQLState.OUTPUT_PARAMS_NOT_ALLOWED),
                     (Object [])null, updateCounts, null );
             } else {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java Tue Jan 23 01:00:23 2018
@@ -61,7 +61,7 @@ public class Configuration {
         return dncPackageConsistencyToken.clone();
     }
 
-    // for ClientDriver.jdbcCompliant()
+    // for ClientAutoloadedDriver.jdbcCompliant()
     public final static boolean jdbcCompliant = true;
 
     private final static String[] dncCompatibleJREVersions =
@@ -109,7 +109,7 @@ public class Configuration {
     // -----------------------Load resource bundles for the driver asap-----------
 
     /**
-     * Used by ClientDriver to accumulate load exceptions
+     * Used by ClientAutoloadedDriver to accumulate load exceptions
      */
     private static SqlException exceptionsOnLoadResources = null;
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCacheInteractor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCacheInteractor.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCacheInteractor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/StatementCacheInteractor.java Tue Jan 23 01:00:23 2018
@@ -28,7 +28,7 @@ import java.util.ArrayList;
 import org.apache.derby.client.am.stmtcache.JDBCStatementCache;
 import org.apache.derby.client.am.stmtcache.StatementKey;
 import org.apache.derby.client.am.stmtcache.StatementKeyFactory;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
@@ -259,7 +259,7 @@ public final class StatementCacheInterac
             StatementKey stmtKey) throws SQLException {
 
         LogicalPreparedStatement logicalPs =
-                ClientDriver.getFactory().newLogicalPreparedStatement(
+                ClientAutoloadedDriver.getFactory().newLogicalPreparedStatement(
                                                     ps, stmtKey, this);
         this.openLogicalStatements.add(logicalPs);
         return logicalPs;
@@ -278,7 +278,7 @@ public final class StatementCacheInterac
             StatementKey stmtKey) throws SQLException {
 
         LogicalCallableStatement logicalCs =
-                ClientDriver.getFactory().newLogicalCallableStatement(
+                ClientAutoloadedDriver.getFactory().newLogicalCallableStatement(
                                                     cs, stmtKey, this);
         this.openLogicalStatements.add(logicalCs);
         return logicalCs;

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCallableStatement.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCallableStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCallableStatement.java Tue Jan 23 01:00:23 2018
@@ -23,7 +23,7 @@ package org.apache.derby.client.net;
 import org.apache.derby.client.am.ClientCallableStatement;
 import org.apache.derby.client.am.MaterialPreparedStatement;
 import org.apache.derby.client.am.SqlException;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.client.ClientPooledConnection;
 
 class NetCallableStatement extends NetPreparedStatement
@@ -72,7 +72,7 @@ class NetCallableStatement extends NetPr
                          int concurrency,
                          int holdability,
                          ClientPooledConnection cpc) throws SqlException {
-        this(ClientDriver.getFactory().newCallableStatement(netAgent,
+        this(ClientAutoloadedDriver.getFactory().newCallableStatement(netAgent,
                 netConnection, sql, type, concurrency, holdability,cpc),
                 netAgent,
                 netConnection);

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java Tue Jan 23 01:00:23 2018
@@ -48,7 +48,7 @@ import org.apache.derby.shared.common.re
 import org.apache.derby.shared.common.i18n.MessageUtil;
 import org.apache.derby.client.am.ClientStatement;
 import org.apache.derby.shared.common.reference.Attribute;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.client.ClientPooledConnection;
 import org.apache.derby.client.am.Agent;
 import org.apache.derby.client.am.ClientConnection;
@@ -159,7 +159,7 @@ public class NetConnection extends Clien
     //it sends RDBAFLRM followed by SQLCARD with null SQLException.
     //Client will parse the SQLCARD and set connectionNull to true if the
     //SQLCARD is empty. If connectionNull=true, connect method in 
-    //ClientDriver will in turn return null connection.
+    //ClientAutoloadedDriver will in turn return null connection.
     private boolean connectionNull = false;
 
     private void setDeferredResetPassword(String password) {
@@ -1053,7 +1053,7 @@ public class NetConnection extends Clien
 
 
     protected ClientDatabaseMetaData newDatabaseMetaData_() {
-            return ClientDriver.getFactory().newNetDatabaseMetaData(netAgent_, this);
+            return ClientAutoloadedDriver.getFactory().newNetDatabaseMetaData(netAgent_, this);
     }
 
     //-------------------private helper methods--------------------------------

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetPreparedStatement.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetPreparedStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetPreparedStatement.java Tue Jan 23 01:00:23 2018
@@ -24,7 +24,7 @@ import org.apache.derby.client.am.Column
 import org.apache.derby.client.am.ClientPreparedStatement;
 import org.apache.derby.client.am.Section;
 import org.apache.derby.client.am.SqlException;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.client.ClientPooledConnection;
 import org.apache.derby.client.am.MaterialPreparedStatement;
 
@@ -93,7 +93,7 @@ class NetPreparedStatement extends NetSt
      */
     NetPreparedStatement(NetAgent netAgent, NetConnection netConnection, String sql, int type, int concurrency, int holdability, int autoGeneratedKeys, String[] columnNames, 
             int[] columnIndexes,  ClientPooledConnection cpc) throws SqlException {
-        this(ClientDriver.getFactory().newPreparedStatement(netAgent,
+        this(ClientAutoloadedDriver.getFactory().newPreparedStatement(netAgent,
                 netConnection, sql, type, concurrency, holdability,
                 autoGeneratedKeys, columnNames, columnIndexes, cpc),
                 netAgent,
@@ -135,7 +135,7 @@ class NetPreparedStatement extends NetSt
                          String sql,
                          Section section,ClientPooledConnection cpc) 
                          throws SqlException {
-        this(ClientDriver.getFactory().newPreparedStatement(netAgent,
+        this(ClientAutoloadedDriver.getFactory().newPreparedStatement(netAgent,
                 netConnection, sql, section,cpc),
                 netAgent,
                 netConnection);

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatement.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatement.java Tue Jan 23 01:00:23 2018
@@ -27,7 +27,7 @@ import org.apache.derby.client.am.Sectio
 import org.apache.derby.client.am.SqlException;
 import org.apache.derby.client.am.ClientStatement;
 import org.apache.derby.client.am.MaterialStatement;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 
 class NetStatement implements MaterialStatement {
 
@@ -94,7 +94,7 @@ class NetStatement implements MaterialSt
 
     // Called by abstract Connection.createStatement().newStatement() for jdbc 2 statements with scroll attributes
     NetStatement(NetAgent netAgent, NetConnection netConnection, int type, int concurrency, int holdability) throws SqlException {
-        this(ClientDriver.getFactory().newStatement(
+        this(ClientAutoloadedDriver.getFactory().newStatement(
                  netAgent,
                  netConnection,
                  type,

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java Tue Jan 23 01:00:23 2018
@@ -35,7 +35,7 @@ import org.apache.derby.client.am.Client
 import org.apache.derby.client.am.StatementCallbackInterface;
 import org.apache.derby.client.am.ClientTypes;
 import org.apache.derby.client.am.Utils;
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.shared.common.i18n.MessageUtil;
 import org.apache.derby.shared.common.reference.MessageId;
 import org.apache.derby.shared.common.reference.SQLState;
@@ -132,7 +132,7 @@ class NetStatementReply extends NetPacka
             if (nullSqlca && peekNumOfColumns() == 0) {
                 netSqlca = parseSQLDARD(columnMetaData, true); // true means to skip the rest of SQLDARD bytes
             } else {
-                columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
+                columnMetaData = ClientAutoloadedDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
                 netSqlca = parseSQLDARD(columnMetaData, false); // false means do not skip SQLDARD bytes.
             }
 
@@ -159,7 +159,7 @@ class NetStatementReply extends NetPacka
             ColumnMetaData columnMetaData = null;
 
             if (columnMetaData == null) {
-                columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
+                columnMetaData = ClientAutoloadedDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
             }
 
             NetSqlca netSqlca = parseSQLDARD(columnMetaData, false);  // false means do not skip SQLDARD bytes
@@ -485,7 +485,7 @@ class NetStatementReply extends NetPacka
             peekCP = parseTypdefsOrMgrlvlovrs();
 
             if (peekCP == CodePoint.SQLDARD) {
-                ColumnMetaData columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
+                ColumnMetaData columnMetaData = ClientAutoloadedDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
                 NetSqlca netSqlca = parseSQLDARD(columnMetaData, false);  // false means do not skip SQLDARD bytes
 
                 //For java stored procedure, we got the resultSetMetaData from server,
@@ -908,7 +908,7 @@ class NetStatementReply extends NetPacka
             statement.cachedCursor_.resetDataBuffer();
             ((NetCursor) statement.cachedCursor_).extdtaData_.clear();
             try {
-                rs = (NetResultSet)ClientDriver.getFactory().newNetResultSet
+                rs = (NetResultSet)ClientAutoloadedDriver.getFactory().newNetResultSet
                         (netAgent_,
                         (NetStatement) statement.getMaterialStatement(),
                         statement.cachedCursor_,
@@ -929,7 +929,7 @@ class NetStatementReply extends NetPacka
             }
         } else {
             try {
-                rs = (NetResultSet)ClientDriver.getFactory().newNetResultSet
+                rs = (NetResultSet)ClientAutoloadedDriver.getFactory().newNetResultSet
                         (netAgent_,
                         (NetStatement) statement.getMaterialStatement(),
                         new NetCursor(netAgent_, qryprctyp),
@@ -1908,7 +1908,7 @@ class NetStatementReply extends NetPacka
     // reply data in the response to an EXCSQLSTT command that invodes a stored
     // procedure
     private ColumnMetaData parseSQLCINRDarray() throws DisconnectException {
-        ColumnMetaData columnMetaData = ClientDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
+        ColumnMetaData columnMetaData = ClientAutoloadedDriver.getFactory().newColumnMetaData(netAgent_.logWriter_);
 
         parseSQLDHROW(columnMetaData);
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetXAConnection.java Tue Jan 23 01:00:23 2018
@@ -32,7 +32,7 @@ import org.apache.derby.client.am.LogWri
 import org.apache.derby.client.BasicClientDataSource;
 import org.apache.derby.shared.common.reference.SQLState;
 
-import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 
 public class NetXAConnection {    
     private NetConnection netCon;
@@ -234,7 +234,7 @@ public class NetXAConnection {
             boolean isXAConn,
             ClientPooledConnection cpc) throws SqlException {
 
-        return (NetConnection)ClientDriver.getFactory().newNetConnection
+        return (NetConnection)ClientAutoloadedDriver.getFactory().newNetConnection
             (logWriter, user, password,dataSource, rmId, isXAConn,cpc);
     }
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientDriver.java Tue Jan 23 01:00:23 2018
@@ -21,500 +21,12 @@
 
 package org.apache.derby.jdbc;
 
-import java.sql.Connection;
-import java.sql.Driver;
-import java.sql.DriverManager;
-import java.sql.DriverPropertyInfo;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
-import java.util.logging.Logger;
-import org.apache.derby.client.am.Configuration;
-import org.apache.derby.client.am.SqlException;
-import org.apache.derby.client.am.Utils;
-import org.apache.derby.client.am.Version;
-import org.apache.derby.client.am.ClientJDBCObjectFactory;
-import org.apache.derby.client.am.ClientMessageId;
-import org.apache.derby.client.am.LogWriter;
-import org.apache.derby.client.net.ClientJDBCObjectFactoryImpl;
-import org.apache.derby.client.net.NetConnection;
-import org.apache.derby.shared.common.reference.Attribute;
-import org.apache.derby.shared.common.reference.SQLState;
-import org.apache.derby.shared.common.reference.MessageId;
-import org.apache.derby.client.BasicClientDataSource;
+import org.apache.derby.client.ClientAutoloadedDriver;
 
 /**
  * The client JDBC driver (type 4) for Derby.
  */
-public class ClientDriver implements Driver {
-    private transient int traceFileSuffixIndex_ = 0;
-
-    private final static int DERBY_REMOTE_PROTOCOL = 1;
-    
-    private static ClientJDBCObjectFactory factoryObject = null;
-
-    static private SQLException exceptionsOnLoadDriver__ = null;
-    // Keep track of the registere driver so that we can deregister it if we're a stored proc.
-    static private ClientDriver registeredDriver__ = null;
-
-    static
-    {
-        registerMe(new ClientDriver());
-    }
-
-    protected static void   registerMe( ClientDriver me )
-    {
-        // The Configuration static clause should execute before the following line does.
-        SqlException ole = Configuration.getExceptionOnLoadResources();
-        
-        if (ole != null) {
-            SQLException e = ole.getSQLException();
-            exceptionsOnLoadDriver__ =
-                Utils.accumulateSQLException(e, exceptionsOnLoadDriver__);
-        }
-        
-        try {
-            registeredDriver__ = me;
-            DriverManager.registerDriver(registeredDriver__);
-        } catch (SQLException e) {
-            // A null log writer is passed, because jdbc 1 sql exceptions are automatically traced
-            exceptionsOnLoadDriver__ =
-                    new SqlException(null, 
-                        new ClientMessageId(SQLState.JDBC_DRIVER_REGISTER)).getSQLException();
-            exceptionsOnLoadDriver__.setNextException(e);
-        }
-    }
-
-    public ClientDriver() {
-    }
-
-    public Connection connect(String url,
-                              Properties properties) throws SQLException {
-        NetConnection conn;
-        
-        checkURLNotNull( url );
-
-        try {    
-            if (exceptionsOnLoadDriver__ != null) {
-                throw exceptionsOnLoadDriver__;
-            }
-
-            if (properties == null) {
-                properties = new Properties();
-            }
-
-            StringTokenizer urlTokenizer =
-                    new StringTokenizer(url, "/:= \t\n\r\f", true);
-
-            int protocol = tokenizeProtocol(url, urlTokenizer);
-            if (protocol == 0) {
-                return null; // unrecognized database URL prefix.
-            }
-
-            String slashOrNull = null;
-            if (protocol == DERBY_REMOTE_PROTOCOL) {
-                try {
-                    slashOrNull = urlTokenizer.nextToken(":/");
-                } catch (NoSuchElementException e) {
-                    // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-                    throw new SqlException(null, 
-                        new ClientMessageId(SQLState.MALFORMED_URL),
-                        e, url);
-                }
-            }
-            String server = tokenizeServerName(urlTokenizer, url);    // "/server"
-            int port = tokenizeOptionalPortNumber(urlTokenizer, url); // "[:port]/"
-            if (port == 0) {
-                port = BasicClientDataSource.propertyDefault_portNumber;
-            }
-
-            // database is the database name and attributes.  This will be
-            // sent to network server as the databaseName
-            String database = tokenizeDatabase(urlTokenizer, url); // "database"
-            Properties augmentedProperties =
-                tokenizeURLProperties(url, properties);
-            database = appendDatabaseAttributes(database,augmentedProperties);
-
-            int traceLevel;
-            try {
-                traceLevel =
-                    BasicClientDataSource.getTraceLevel(augmentedProperties);
-            } catch (NumberFormatException e) {
-                // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-                throw new SqlException(null, 
-                    new ClientMessageId(SQLState.TRACELEVEL_FORMAT_INVALID), e);
-            }
-
-            // Jdbc 1 connections will write driver trace info on a
-            // driver-wide basis using the jdbc 1 driver manager log writer.
-            // This log writer may be narrowed to the connection-level
-            // This log writer will be passed to the agent constructor.
-            LogWriter dncLogWriter =
-                BasicClientDataSource.computeDncLogWriterForNewConnection(
-                    DriverManager.getLogWriter(),
-                    BasicClientDataSource.getTraceDirectory(
-                        augmentedProperties),
-                    BasicClientDataSource.getTraceFile(
-                        augmentedProperties),
-                    BasicClientDataSource.getTraceFileAppend(
-                        augmentedProperties),
-                    traceLevel,
-                    "_driver",
-                    traceFileSuffixIndex_++);
-            
-            
-            conn = (NetConnection)getFactory().
-                    newNetConnection(dncLogWriter,
-                    DriverManager.getLoginTimeout(),
-                    server,
-                    port,
-                    database,
-                    augmentedProperties);
-        } catch(SqlException se) {
-            throw se.getSQLException();
-        }
-        
-        if(conn.isConnectionNull())
-            return null;
-        
-        return conn;
-    }
-
-    /**
-     * Append attributes to the database name except for user/password 
-     * which are sent as part of the protocol, and SSL which is used 
-     * locally in the client.
-     * Other attributes will  be sent to the server with the database name
-     * Assumes augmentedProperties is not null
-     * 
-     * @param database - Short database name
-     * @param augmentedProperties - Set of properties to append as attributes
-     * @return databaseName + attributes (e.g. mydb;create=true) 
-     */
-    private String appendDatabaseAttributes(String database, Properties augmentedProperties) {
-    
-        StringBuffer longDatabase = new StringBuffer(database);
-        for (Enumeration keys = augmentedProperties.propertyNames();
-             keys.hasMoreElements() ;)
-        {
-            String key = (String) keys.nextElement();
-            if (key.equals(Attribute.USERNAME_ATTR) || 
-                key.equals(Attribute.PASSWORD_ATTR) ||
-                key.equals(Attribute.SSL_ATTR))
-                continue;
-            longDatabase.append(";" + key + "=" + augmentedProperties.getProperty(key));
-        }
-        return longDatabase.toString();
-    }
-
-    public boolean acceptsURL(String url) throws SQLException {
-
-        checkURLNotNull( url );
-        
-        try
-        {
-            StringTokenizer urlTokenizer =
-                    new StringTokenizer(url, "/:=; \t\n\r\f", true);
-            int protocol = tokenizeProtocol(url, urlTokenizer);
-            return protocol != 0;
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
-    }
-    private void    checkURLNotNull( String url ) throws SQLException
-    {
-        if ( url == null )
-        {
-            throw (new SqlException
-                (
-                 null, 
-                 new ClientMessageId( SQLState.MALFORMED_URL), "null"
-                 )).getSQLException();
-        }
-    }
-
-    public DriverPropertyInfo[] getPropertyInfo(
-            String url,
-            Properties properties) throws SQLException {
-
-        DriverPropertyInfo driverPropertyInfo[] = new DriverPropertyInfo[2];
-
-        // If there are no properties set already,
-        // then create a dummy properties just to make the calls go thru.
-        if (properties == null) {
-            properties = new Properties();
-        }
-
-        driverPropertyInfo[0] =
-            new DriverPropertyInfo(
-                Attribute.USERNAME_ATTR,
-                properties.getProperty(
-                    Attribute.USERNAME_ATTR,
-                    BasicClientDataSource.propertyDefault_user));
-
-        driverPropertyInfo[1] =
-                new DriverPropertyInfo(Attribute.PASSWORD_ATTR,
-                        properties.getProperty(Attribute.PASSWORD_ATTR));
-
-        driverPropertyInfo[0].description =
-            SqlException.getMessageUtil().getTextMessage(
-                MessageId.CONN_USERNAME_DESCRIPTION);
-        driverPropertyInfo[1].description =
-            SqlException.getMessageUtil().getTextMessage(
-                MessageId.CONN_PASSWORD_DESCRIPTION);
-
-        driverPropertyInfo[0].required = true;
-        driverPropertyInfo[1].required = false; // depending on the security mechanism
-
-        return driverPropertyInfo;
-    }
-
-    public int getMajorVersion() {
-        return Version.getMajorVersion();
-    }
-
-    public int getMinorVersion() {
-        return Version.getMinorVersion();
-    }
-
-    public boolean jdbcCompliant() {
-        return Configuration.jdbcCompliant;
-    }
-
-    ////////////////////////////////////////////////////////////////////
-    //
-    // INTRODUCED BY JDBC 4.1 IN JAVA 7
-    //
-    ////////////////////////////////////////////////////////////////////
-
-    public  Logger getParentLogger()
-        throws SQLFeatureNotSupportedException
-    {
-        getFactory();
-        throw (SQLFeatureNotSupportedException)
-            (
-             new SqlException( null, new ClientMessageId(SQLState.NOT_IMPLEMENTED), "getParentLogger" )
-             ).getSQLException();
-    }
-
-    // ----------------helper methods---------------------------------------------
-
-    // Tokenize one of the following:
-    //  "jdbc:derby:"
-    // and return 0 if the protcol is unrecognized
-    // return DERBY_PROTOCOL for "jdbc:derby"
-    private static int tokenizeProtocol(
-            String url,
-            StringTokenizer urlTokenizer) throws SqlException {
-
-        // Is this condition necessary, StringTokenizer constructor may do this for us
-        if (url == null) {
-            return 0;
-        }
-
-        if (urlTokenizer == null) {
-            return 0;
-        }
-
-        try {
-            String jdbc = urlTokenizer.nextToken(":");
-            if (!jdbc.equals("jdbc")) {
-                return 0;
-            }
-            if (!urlTokenizer.nextToken(":").equals(":")) {
-                return 0; // Skip over the first colon in jdbc:derby:
-            }
-            String dbname = urlTokenizer.nextToken(":");
-            int protocol = 0;
-            if (dbname.equals("derby") && (url.indexOf("derby://") != -1)) {
-                // For Derby AS need to check for // since jdbc:derby: is also the
-                // embedded prefix
-                protocol = DERBY_REMOTE_PROTOCOL;
-            } else {
-                return 0;
-            }
-
-            if (!urlTokenizer.nextToken(":").equals(":")) {
-                return 0; // Skip over the second colon in jdbc:derby:
-            }
-
-            return protocol;
-        } catch (NoSuchElementException e) {
-            return 0;
-        }
-    }
-
-    // tokenize "/server" from URL jdbc:derby://server:port/
-    // returns server name
-    private static String tokenizeServerName(StringTokenizer urlTokenizer,
-                                             String url) throws SqlException {
-        try {
-            if (!urlTokenizer.nextToken("/").equals("/"))
-            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-            {
-                throw new SqlException(null, 
-                    new ClientMessageId(SQLState.MALFORMED_URL), url);
-            }
-            return urlTokenizer.nextToken("/:");
-        } catch (NoSuchElementException e) {
-            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-                throw new SqlException(null, 
-                    new ClientMessageId(SQLState.MALFORMED_URL), url);
-        }
-    }
-
-    // tokenize "[:portNumber]/" from URL jdbc:derby://server[:port]/
-    // returns the portNumber or zero if portNumber is not specified.
-    private static int tokenizeOptionalPortNumber(StringTokenizer urlTokenizer,
-                                                  String url) throws SqlException {
-        try {
-            String firstToken = urlTokenizer.nextToken(":/");
-            if (firstToken.equals(":")) {
-                String port = urlTokenizer.nextToken("/");
-                if (!urlTokenizer.nextToken("/").equals("/")) {
-                    // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-                    throw new SqlException(null, 
-                        new ClientMessageId(SQLState.MALFORMED_URL), url);
-                }
-                return Integer.parseInt(port);
-            } else if (firstToken.equals("/")) {
-                return 0;
-            } else {
-                // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-                throw new SqlException(null, 
-                    new ClientMessageId(SQLState.MALFORMED_URL), url);
-            }
-        } catch (NoSuchElementException e) {
-            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-            throw new SqlException(null, 
-                new ClientMessageId(SQLState.MALFORMED_URL), e, url);
-        }
-    }
-
-    //return database name
-    private static String tokenizeDatabase(StringTokenizer urlTokenizer,
-                                           String url) throws SqlException {
-        try {
-            // DERBY-618 - database name can contain spaces in the path
-            String databaseName = urlTokenizer.nextToken("\t\n\r\f;");
-            return databaseName;
-        } catch (NoSuchElementException e) {
-            // A null log writer is passed, because jdbc 1 sqlexceptions are automatically traced
-            throw new SqlException(null, 
-                new ClientMessageId(SQLState.MALFORMED_URL), e, url);
-        }
-    }
-
-    private static Properties tokenizeURLProperties(String url,
-                                                    Properties properties)
-            throws SqlException {
-        String attributeString = null;
-        int attributeIndex = -1;
-
-        if ((url != null) &&
-                ((attributeIndex = url.indexOf(";")) != -1)) {
-            attributeString = url.substring(attributeIndex);
-        }
-
-        return BasicClientDataSource.tokenizeAttributes(
-            attributeString, properties);
-    }
-    
-    /**
-     *This method returns an Implementation
-     *of ClientJDBCObjectFactory depending on
-     *VM under use
-     *Currently it returns either
-     *ClientJDBCObjectFactoryImpl
-     *(or)
-     *ClientJDBCObjectFactoryImpl42
-     */
-    
-    public static ClientJDBCObjectFactory getFactory() {
-        // System.err.println("factoryObject="+factoryObject);
-
-        if(factoryObject!=null)
-            return factoryObject;
-        if (Configuration.supportsJDBC42()) {
-            factoryObject = createJDBC42FactoryImpl();
-        } else {
-            factoryObject = createDefaultFactoryImpl();
-        }
-        return factoryObject;
-    }
-    
-    /**
-     *Returns an instance of the ClientJDBCObjectFactoryImpl class
-     */
-    private static ClientJDBCObjectFactory createDefaultFactoryImpl() {
-        return  new ClientJDBCObjectFactoryImpl();
-    }
-    
-    /**
-     *Returns an instance of the ClientJDBCObjectFactoryImpl40 class
-     *If a ClassNotFoundException occurs then it returns an
-     *instance of ClientJDBCObjectFactoryImpl
-     *
-     *If a future version of JDBC comes then
-     *a similar method would be added say createJDBCXXFactoryImpl
-     *in which if  the class is not found then it would
-     *return the lower version thus having a sort of cascading effect
-     *until it gets a valid instance
-     */
-    
-    private static ClientJDBCObjectFactory createJDBC40FactoryImpl() {
-        final String factoryName =
-                "org.apache.derby.client.net.ClientJDBCObjectFactoryImpl40";
-        try {
-            Class<?> clazz = Class.forName(factoryName);
-            return (ClientJDBCObjectFactory) clazz.getConstructor().newInstance();
-        } catch (ClassNotFoundException cnfe) {
-            return createDefaultFactoryImpl();
-        } catch (InstantiationException ie) {
-            return createDefaultFactoryImpl();
-        } catch (IllegalAccessException iae) {
-            return createDefaultFactoryImpl();
-        } catch (NoSuchMethodException iae) {
-            return createDefaultFactoryImpl();
-        } catch (java.lang.reflect.InvocationTargetException iae) {
-            return createDefaultFactoryImpl();
-        }
-    }
-
-    /**
-     *Returns an instance of the ClientJDBCObjectFactoryImpl42 class
-     *If a ClassNotFoundException occurs then it returns an
-     *instance of the most refined ClientJDBCObjectFactoryImpl possible
-     *
-     *If a future version of JDBC comes then
-     *a similar method would be added say createJDBCXXFactoryImpl
-     *in which if  the class is not found then it would
-     *return the lower version thus having a sort of cascading effect
-     *until it gets a valid instance
-     */
-    
-    private static ClientJDBCObjectFactory createJDBC42FactoryImpl() {
-        final String factoryName =
-                "org.apache.derby.client.net.ClientJDBCObjectFactoryImpl42";
-        try {
-            Class<?> clazz = Class.forName(factoryName);
-            return (ClientJDBCObjectFactory) clazz.getConstructor().newInstance();
-        } catch (ClassNotFoundException cnfe) {
-            return createJDBC40FactoryImpl();
-        } catch (InstantiationException ie) {
-            return createJDBC40FactoryImpl();
-        } catch (IllegalAccessException iae) {
-            return createJDBC40FactoryImpl();
-        } catch (NoSuchMethodException iae) {
-            return createJDBC40FactoryImpl();
-        } catch (java.lang.reflect.InvocationTargetException iae) {
-            return createJDBC40FactoryImpl();
-        }
-    }
-
+public class ClientDriver extends ClientAutoloadedDriver
+{
+    public ClientDriver() { super(); }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/JarLoader.java Tue Jan 23 01:00:23 2018
@@ -214,6 +214,7 @@ final class JarLoader extends SecureClas
         return
           (
            className.startsWith("org.apache.derby.iapi.jdbc.AutoloadedDriver")
+           || className.startsWith("org.apache.derby.iapi.client.ClientAutoloadedDriver")
            );
     }
   

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Driver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Driver.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Driver.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Driver.java Tue Jan 23 01:00:23 2018
@@ -27,6 +27,7 @@ import java.util.logging.Logger;
 
 import org.apache.derby.iapi.jdbc.AutoloadedDriver;
 import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.client.ClientAutoloadedDriver;
 import org.apache.derby.iapi.jdbc.InternalDriver;
 
 /**
@@ -45,6 +46,7 @@ public  class   Wrapper41Driver
     private AutoloadedDriver    _embedded;
     private InternalDriver      _driver40;
     private ClientDriver      _netclient;
+    private ClientAutoloadedDriver      _netautoloaded;
     
     ///////////////////////////////////////////////////////////////////////
     //
@@ -57,6 +59,8 @@ public  class   Wrapper41Driver
         if ( wrapped instanceof AutoloadedDriver ) { _embedded = (AutoloadedDriver) wrapped; }
         else if ( wrapped instanceof InternalDriver ) { _driver40 = (InternalDriver) wrapped; }
         else if ( wrapped instanceof ClientDriver ) { _netclient = (ClientDriver) wrapped; }
+        else if ( wrapped instanceof ClientAutoloadedDriver )
+        { _netautoloaded = (ClientAutoloadedDriver) wrapped; }
         else { throw nothingWrapped( wrapped ); }
     }
     
@@ -71,6 +75,7 @@ public  class   Wrapper41Driver
         if ( _embedded != null ) { return _embedded.getParentLogger(); }
         else if ( _driver40 != null ) { return _driver40.getParentLogger(); }
         else if ( _netclient != null ) { return _netclient.getParentLogger(); }
+        else if ( _netautoloaded != null ) { return _netautoloaded.getParentLogger(); }
         else { throw nothingWrapped( null ); }
     }
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/AutoloadTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/AutoloadTest.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/AutoloadTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/AutoloadTest.java Tue Jan 23 01:00:23 2018
@@ -397,7 +397,7 @@ public class AutoloadTest extends BaseJD
     }
     private String  getClientDriverName()
     {
-        return "org.apache.derby.jdbc.ClientDriver";
+        return "org.apache.derby.client.ClientAutoloadedDriver";
     }
     
     /**

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DriverTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DriverTest.java?rev=1821953&r1=1821952&r2=1821953&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DriverTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DriverTest.java Tue Jan 23 01:00:23 2018
@@ -168,7 +168,7 @@ public class DriverTest extends BaseJDBC
         // Test that the driver class is the expected one. Currently, the same
         // driver class is used regardless of JDBC version.
         println( "Driver is a " + driver.getClass().getName() );
-        assertEquals(usingEmbedded() ? "AutoloadedDriver" : "ClientDriver",
+        assertEquals(usingEmbedded() ? "AutoloadedDriver" : "ClientAutoloadedDriver",
                      driver.getClass().getSimpleName());
 
         // test that null connection URLs raise a SQLException per JDBC 4.2 spec clarification