src/share/classes/java/sql/DriverManager.java

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.sql;
  27 
  28 import java.util.Iterator;
  29 import java.util.ServiceLoader;
  30 import java.security.AccessController;
  31 import java.security.PrivilegedAction;

  32 import java.util.concurrent.CopyOnWriteArrayList;
  33 import sun.reflect.CallerSensitive;
  34 import sun.reflect.Reflection;
  35 
  36 
  37 /**
  38  * <P>The basic service for managing a set of JDBC drivers.<br>
  39  * <B>NOTE:</B> The {@link javax.sql.DataSource} interface, new in the
  40  * JDBC 2.0 API, provides another way to connect to a data source.
  41  * The use of a <code>DataSource</code> object is the preferred means of
  42  * connecting to a data source.
  43  *
  44  * <P>As part of its initialization, the <code>DriverManager</code> class will
  45  * attempt to load the driver classes referenced in the "jdbc.drivers"
  46  * system property. This allows a user to customize the JDBC Drivers
  47  * used by their applications. For example in your
  48  * ~/.hotjava/properties file you might specify:
  49  * <pre>
  50  * <CODE>jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver</CODE>
  51  * </pre>


  71  *
  72  * <P>
  73  * Starting with the Java 2 SDK, Standard Edition, version 1.3, a
  74  * logging stream can be set only if the proper
  75  * permission has been granted.  Normally this will be done with
  76  * the tool PolicyTool, which can be used to grant <code>permission
  77  * java.sql.SQLPermission "setLog"</code>.
  78  * @see Driver
  79  * @see Connection
  80  */
  81 public class DriverManager {
  82 
  83 
  84     // List of registered JDBC drivers
  85     private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
  86     private static volatile int loginTimeout = 0;
  87     private static volatile java.io.PrintWriter logWriter = null;
  88     private static volatile java.io.PrintStream logStream = null;
  89     // Used in println() to synchronize logWriter
  90     private final static  Object logSync = new Object();


  91 
  92     /* Prevent the DriverManager class from being instantiated. */
  93     private DriverManager(){}
  94 
  95 
  96     /**
  97      * Load the initial JDBC drivers by checking the System property
  98      * jdbc.properties and then use the {@code ServiceLoader} mechanism
  99      */
 100     static {
 101         loadInitialDrivers();
 102         println("JDBC DriverManager initialized");
 103     }
 104 
 105     /**
 106      * The <code>SQLPermission</code> constant that allows the
 107      * setting of the logging stream.
 108      * @since 1.3
 109      */
 110     final static SQLPermission SET_LOG_PERMISSION =
 111         new SQLPermission("setLog");
 112 
 113     /**
 114      * The {@code SQLPermission} constant that allows the
 115      * un-register a registered JDBC driver.
 116      * @since 1.8
 117      */
 118     final static SQLPermission DEREGISTER_DRIVER_PERMISSION =
 119         new SQLPermission("deregisterDriver");
 120 
 121     //--------------------------JDBC 2.0-----------------------------
 122 
 123     /**
 124      * Retrieves the log writer.


 274      * Attempts to locate a driver that understands the given URL.
 275      * The <code>DriverManager</code> attempts to select an appropriate driver from
 276      * the set of registered JDBC drivers.
 277      *
 278      * @param url a database URL of the form
 279      *     <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
 280      * @return a <code>Driver</code> object representing a driver
 281      * that can connect to the given URL
 282      * @exception SQLException if a database access error occurs
 283      */
 284     @CallerSensitive
 285     public static Driver getDriver(String url)
 286         throws SQLException {
 287 
 288         println("DriverManager.getDriver(\"" + url + "\")");
 289 
 290         Class<?> callerClass = Reflection.getCallerClass();
 291 
 292         // Walk through the loaded registeredDrivers attempting to locate someone
 293         // who understands the given URL.
 294         for (DriverInfo aDriver : registeredDrivers) {
 295             // If the caller does not have permission to load the driver then
 296             // skip it.
 297             if(isDriverAllowed(aDriver.driver, callerClass)) {
 298                 try {
 299                     if(aDriver.driver.acceptsURL(url)) {
 300                         // Success!
 301                         println("getDriver returning " + aDriver.driver.getClass().getName());
 302                     return (aDriver.driver);
 303                     }
 304 
 305                 } catch(SQLException sqe) {
 306                     // Drop through and try the next driver.
 307                 }
 308             } else {
 309                 println("    skipping: " + aDriver.driver.getClass().getName());
 310             }
 311 
 312         }
 313 
 314         println("getDriver: no suitable driver");
 315         throw new SQLException("No suitable driver", "08001");
 316     }
 317 
 318 
 319     /**
 320      * Registers the given driver with the {@code DriverManager}.
 321      * A newly-loaded driver class should call
 322      * the method {@code registerDriver} to make itself
 323      * known to the {@code DriverManager}. If the driver is currently
 324      * registered, no action is taken.
 325      *
 326      * @param driver the new JDBC Driver that is to be registered with the
 327      *               {@code DriverManager}
 328      * @exception SQLException if a database access error occurs
 329      * @exception NullPointerException if {@code driver} is null
 330      */
 331     public static synchronized void registerDriver(java.sql.Driver driver)
 332         throws SQLException {
 333 
 334         registerDriver(driver, null);
 335     }
 336 
 337     /**
 338      * Registers the given driver with the {@code DriverManager}.
 339      * A newly-loaded driver class should call
 340      * the method {@code registerDriver} to make itself
 341      * known to the {@code DriverManager}. If the driver is currently
 342      * registered, no action is taken.
 343      *
 344      * @param driver the new JDBC Driver that is to be registered with the
 345      *               {@code DriverManager}
 346      * @param da     the {@code DriverAction} implementation to be used when
 347      *               {@code DriverManager#deregisterDriver} is called
 348      * @exception SQLException if a database access error occurs
 349      * @exception NullPointerException if {@code driver} is null
 350      * @since 1.8
 351      */
 352     public static synchronized void registerDriver(java.sql.Driver driver,
 353             DriverAction da)
 354         throws SQLException {
 355 
 356         /* Register the driver if it has not already been added to our list */
 357         if(driver != null) {
 358             registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
 359         } else {
 360             // This is for compatibility with the original DriverManager
 361             throw new NullPointerException();
 362         }
 363 
 364         println("registerDriver: " + driver);
 365 
 366     }
 367 
 368     /**
 369      * Removes the specified driver from the {@code DriverManager}'s list of
 370      * registered drivers.
 371      * <p>
 372      * If a {@code null} value is specified for the driver to be removed, then no


 423             println("    couldn't find driver to unload");
 424         }
 425     }
 426 
 427     /**
 428      * Retrieves an Enumeration with all of the currently loaded JDBC drivers
 429      * to which the current caller has access.
 430      *
 431      * <P><B>Note:</B> The classname of a driver can be found using
 432      * <CODE>d.getClass().getName()</CODE>
 433      *
 434      * @return the list of JDBC Drivers loaded by the caller's class loader
 435      */
 436     @CallerSensitive
 437     public static java.util.Enumeration<Driver> getDrivers() {
 438         java.util.Vector<Driver> result = new java.util.Vector<>();
 439 
 440         Class<?> callerClass = Reflection.getCallerClass();
 441 
 442         // Walk through the loaded registeredDrivers.
 443         for(DriverInfo aDriver : registeredDrivers) {
 444             // If the caller does not have permission to load the driver then
 445             // skip it.
 446             if(isDriverAllowed(aDriver.driver, callerClass)) {
 447                 result.addElement(aDriver.driver);
 448             } else {
 449                 println("    skipping: " + aDriver.getClass().getName());
 450             }
 451         }
 452         return (result.elements());
 453     }
 454 
 455 
 456     /**
 457      * Sets the maximum time in seconds that a driver will wait
 458      * while attempting to connect to a database once the driver has
 459      * been identified.
 460      *
 461      * @param seconds the login time limit in seconds; zero means there is no limit
 462      * @see #getLoginTimeout
 463      */


 547         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
 548         return isDriverAllowed(driver, callerCL);
 549     }
 550 
 551     private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
 552         boolean result = false;
 553         if(driver != null) {
 554             Class<?> aClass = null;
 555             try {
 556                 aClass =  Class.forName(driver.getClass().getName(), true, classLoader);
 557             } catch (Exception ex) {
 558                 result = false;
 559             }
 560 
 561              result = ( aClass == driver.getClass() ) ? true : false;
 562         }
 563 
 564         return result;
 565     }
 566 
 567     private static void loadInitialDrivers() {

















 568         String drivers;





 569         try {
 570             drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
 571                 public String run() {
 572                     return System.getProperty("jdbc.drivers");
 573                 }
 574             });
 575         } catch (Exception ex) {
 576             drivers = null;
 577         }
 578         // If the driver is packaged as a Service Provider, load it.
 579         // Get all the drivers through the classloader
 580         // exposed as a java.sql.Driver.class service.
 581         // ServiceLoader.load() replaces the sun.misc.Providers()
 582 
 583         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 584             public Void run() {
 585 
 586                 ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
 587                 Iterator<Driver> driversIterator = loadedDrivers.iterator();
 588 
 589                 /* Load these drivers, so that they can be instantiated.
 590                  * It may be the case that the driver class may not be there
 591                  * i.e. there may be a packaged driver with the service class
 592                  * as implementation of java.sql.Driver but the actual class
 593                  * may be missing. In that case a java.util.ServiceConfigurationError
 594                  * will be thrown at runtime by the VM trying to locate


 608                 return null;
 609             }
 610         });
 611 
 612         println("DriverManager.initialize: jdbc.drivers = " + drivers);
 613 
 614         if (drivers == null || drivers.equals("")) {
 615             return;
 616         }
 617         String[] driversList = drivers.split(":");
 618         println("number of Drivers:" + driversList.length);
 619         for (String aDriver : driversList) {
 620             try {
 621                 println("DriverManager.Initialize: loading " + aDriver);
 622                 Class.forName(aDriver, true,
 623                         ClassLoader.getSystemClassLoader());
 624             } catch (Exception ex) {
 625                 println("DriverManager.Initialize: load failed: " + ex);
 626             }
 627         }



 628     }
 629 
 630 
 631     //  Worker method called by the public getConnection() methods.
 632     private static Connection getConnection(
 633         String url, java.util.Properties info, Class<?> caller) throws SQLException {
 634         /*
 635          * When callerCl is null, we should check the application's
 636          * (which is invoking this class indirectly)
 637          * classloader, so that the JDBC driver class outside rt.jar
 638          * can be loaded from here.
 639          */
 640         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
 641         synchronized(DriverManager.class) {
 642             // synchronize loading of the correct classloader.
 643             if (callerCL == null) {
 644                 callerCL = Thread.currentThread().getContextClassLoader();
 645             }
 646         }
 647 
 648         if(url == null) {
 649             throw new SQLException("The url cannot be null", "08001");
 650         }
 651 
 652         println("DriverManager.getConnection(\"" + url + "\")");
 653 
 654         // Walk through the loaded registeredDrivers attempting to make a connection.
 655         // Remember the first exception that gets raised so we can reraise it.
 656         SQLException reason = null;
 657 
 658         for(DriverInfo aDriver : registeredDrivers) {
 659             // If the caller does not have permission to load the driver then
 660             // skip it.
 661             if(isDriverAllowed(aDriver.driver, callerCL)) {
 662                 try {
 663                     println("    trying " + aDriver.driver.getClass().getName());
 664                     Connection con = aDriver.driver.connect(url, info);
 665                     if (con != null) {
 666                         // Success!
 667                         println("getConnection returning " + aDriver.driver.getClass().getName());
 668                         return (con);
 669                     }
 670                 } catch (SQLException ex) {
 671                     if (reason == null) {
 672                         reason = ex;
 673                     }
 674                 }
 675 
 676             } else {
 677                 println("    skipping: " + aDriver.getClass().getName());
 678             }




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.sql;
  27 
  28 import java.util.Iterator;
  29 import java.util.ServiceLoader;
  30 import java.security.AccessController;
  31 import java.security.PrivilegedAction;
  32 import java.util.PropertyPermission;
  33 import java.util.concurrent.CopyOnWriteArrayList;
  34 import sun.reflect.CallerSensitive;
  35 import sun.reflect.Reflection;
  36 
  37 
  38 /**
  39  * <P>The basic service for managing a set of JDBC drivers.<br>
  40  * <B>NOTE:</B> The {@link javax.sql.DataSource} interface, new in the
  41  * JDBC 2.0 API, provides another way to connect to a data source.
  42  * The use of a <code>DataSource</code> object is the preferred means of
  43  * connecting to a data source.
  44  *
  45  * <P>As part of its initialization, the <code>DriverManager</code> class will
  46  * attempt to load the driver classes referenced in the "jdbc.drivers"
  47  * system property. This allows a user to customize the JDBC Drivers
  48  * used by their applications. For example in your
  49  * ~/.hotjava/properties file you might specify:
  50  * <pre>
  51  * <CODE>jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver</CODE>
  52  * </pre>


  72  *
  73  * <P>
  74  * Starting with the Java 2 SDK, Standard Edition, version 1.3, a
  75  * logging stream can be set only if the proper
  76  * permission has been granted.  Normally this will be done with
  77  * the tool PolicyTool, which can be used to grant <code>permission
  78  * java.sql.SQLPermission "setLog"</code>.
  79  * @see Driver
  80  * @see Connection
  81  */
  82 public class DriverManager {
  83 
  84 
  85     // List of registered JDBC drivers
  86     private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
  87     private static volatile int loginTimeout = 0;
  88     private static volatile java.io.PrintWriter logWriter = null;
  89     private static volatile java.io.PrintStream logStream = null;
  90     // Used in println() to synchronize logWriter
  91     private final static Object logSync = new Object();
  92     private static volatile boolean driversInitialized;
  93     private static final String JDBC_DRIVERS_PROPERTY = "jdbc.drivers";
  94 
  95     /* Prevent the DriverManager class from being instantiated. */
  96     private DriverManager(){}
  97 










  98     /**
  99      * The <code>SQLPermission</code> constant that allows the
 100      * setting of the logging stream.
 101      * @since 1.3
 102      */
 103     final static SQLPermission SET_LOG_PERMISSION =
 104         new SQLPermission("setLog");
 105 
 106     /**
 107      * The {@code SQLPermission} constant that allows the
 108      * un-register a registered JDBC driver.
 109      * @since 1.8
 110      */
 111     final static SQLPermission DEREGISTER_DRIVER_PERMISSION =
 112         new SQLPermission("deregisterDriver");
 113 
 114     //--------------------------JDBC 2.0-----------------------------
 115 
 116     /**
 117      * Retrieves the log writer.


 267      * Attempts to locate a driver that understands the given URL.
 268      * The <code>DriverManager</code> attempts to select an appropriate driver from
 269      * the set of registered JDBC drivers.
 270      *
 271      * @param url a database URL of the form
 272      *     <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
 273      * @return a <code>Driver</code> object representing a driver
 274      * that can connect to the given URL
 275      * @exception SQLException if a database access error occurs
 276      */
 277     @CallerSensitive
 278     public static Driver getDriver(String url)
 279         throws SQLException {
 280 
 281         println("DriverManager.getDriver(\"" + url + "\")");
 282         
 283         Class<?> callerClass = Reflection.getCallerClass();
 284 
 285         // Walk through the loaded registeredDrivers attempting to locate someone
 286         // who understands the given URL.
 287         for (DriverInfo aDriver : getRegisteredDrivers()) {
 288             // If the caller does not have permission to load the driver then
 289             // skip it.
 290             if(isDriverAllowed(aDriver.driver, callerClass)) {
 291                 try {
 292                     if(aDriver.driver.acceptsURL(url)) {
 293                         // Success!
 294                         println("getDriver returning " + aDriver.driver.getClass().getName());
 295                     return (aDriver.driver);
 296                     }
 297 
 298                 } catch(SQLException sqe) {
 299                     // Drop through and try the next driver.
 300                 }
 301             } else {
 302                 println("    skipping: " + aDriver.driver.getClass().getName());
 303             }
 304 
 305         }
 306 
 307         println("getDriver: no suitable driver");
 308         throw new SQLException("No suitable driver", "08001");
 309     }
 310 
 311 
 312     /**
 313      * Registers the given driver with the {@code DriverManager}.
 314      * A newly-loaded driver class should call
 315      * the method {@code registerDriver} to make itself
 316      * known to the {@code DriverManager}. If the driver is currently
 317      * registered, no action is taken.
 318      *
 319      * @param driver the new JDBC Driver that is to be registered with the
 320      *               {@code DriverManager}
 321      * @exception SQLException if a database access error occurs
 322      * @exception NullPointerException if {@code driver} is null
 323      */
 324     public static void registerDriver(java.sql.Driver driver)
 325         throws SQLException {
 326 
 327         registerDriver(driver, null);
 328     }
 329 
 330     /**
 331      * Registers the given driver with the {@code DriverManager}.
 332      * A newly-loaded driver class should call
 333      * the method {@code registerDriver} to make itself
 334      * known to the {@code DriverManager}. If the driver is currently
 335      * registered, no action is taken.
 336      *
 337      * @param driver the new JDBC Driver that is to be registered with the
 338      *               {@code DriverManager}
 339      * @param da     the {@code DriverAction} implementation to be used when
 340      *               {@code DriverManager#deregisterDriver} is called
 341      * @exception SQLException if a database access error occurs
 342      * @exception NullPointerException if {@code driver} is null
 343      * @since 1.8
 344      */
 345     public static void registerDriver(java.sql.Driver driver,
 346             DriverAction da)
 347         throws SQLException {
 348         
 349         /* Register the driver if it has not already been added to our list */
 350         if(driver != null) {
 351             registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
 352         } else {
 353             // This is for compatibility with the original DriverManager
 354             throw new NullPointerException();
 355         }
 356 
 357         println("registerDriver: " + driver);
 358 
 359     }
 360 
 361     /**
 362      * Removes the specified driver from the {@code DriverManager}'s list of
 363      * registered drivers.
 364      * <p>
 365      * If a {@code null} value is specified for the driver to be removed, then no


 416             println("    couldn't find driver to unload");
 417         }
 418     }
 419 
 420     /**
 421      * Retrieves an Enumeration with all of the currently loaded JDBC drivers
 422      * to which the current caller has access.
 423      *
 424      * <P><B>Note:</B> The classname of a driver can be found using
 425      * <CODE>d.getClass().getName()</CODE>
 426      *
 427      * @return the list of JDBC Drivers loaded by the caller's class loader
 428      */
 429     @CallerSensitive
 430     public static java.util.Enumeration<Driver> getDrivers() {
 431         java.util.Vector<Driver> result = new java.util.Vector<>();
 432   
 433         Class<?> callerClass = Reflection.getCallerClass();
 434 
 435         // Walk through the loaded registeredDrivers.
 436         for(DriverInfo aDriver : getRegisteredDrivers()) {
 437             // If the caller does not have permission to load the driver then
 438             // skip it.
 439             if(isDriverAllowed(aDriver.driver, callerClass)) {
 440                 result.addElement(aDriver.driver);
 441             } else {
 442                 println("    skipping: " + aDriver.getClass().getName());
 443             }
 444         }
 445         return (result.elements());
 446     }
 447 
 448 
 449     /**
 450      * Sets the maximum time in seconds that a driver will wait
 451      * while attempting to connect to a database once the driver has
 452      * been identified.
 453      *
 454      * @param seconds the login time limit in seconds; zero means there is no limit
 455      * @see #getLoginTimeout
 456      */


 540         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
 541         return isDriverAllowed(driver, callerCL);
 542     }
 543 
 544     private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
 545         boolean result = false;
 546         if(driver != null) {
 547             Class<?> aClass = null;
 548             try {
 549                 aClass =  Class.forName(driver.getClass().getName(), true, classLoader);
 550             } catch (Exception ex) {
 551                 result = false;
 552             }
 553 
 554              result = ( aClass == driver.getClass() ) ? true : false;
 555         }
 556 
 557         return result;
 558     }
 559 
 560     /*
 561      * Return the registered java.sql.Drivers and call loadInitialDrivers
 562      * if needed
 563      */
 564     private static CopyOnWriteArrayList<DriverInfo> getRegisteredDrivers() {
 565         // Check to see if we need to load the initial drivers
 566         if (!driversInitialized) {
 567             loadInitialDrivers();
 568         }
 569         return registeredDrivers;
 570 
 571     }
 572 
 573     /*
 574      * Load the initial JDBC drivers by checking the System property
 575      * jdbc.properties and then use the {@code ServiceLoader} mechanism
 576      */
 577     private synchronized static void loadInitialDrivers() {
 578         String drivers;
 579 
 580         if (driversInitialized) {
 581             return;
 582         }
 583         
 584         try {
 585             drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
 586                 public String run() {
 587                     return System.getProperty(JDBC_DRIVERS_PROPERTY);
 588                 }
 589             }, null, new PropertyPermission(JDBC_DRIVERS_PROPERTY, "read"));
 590         } catch (Exception ex) {
 591             drivers = null;
 592         }
 593         // If the driver is packaged as a Service Provider, load it.
 594         // Get all the drivers through the classloader
 595         // exposed as a java.sql.Driver.class service.
 596         // ServiceLoader.load() replaces the sun.misc.Providers()
 597 
 598         AccessController.doPrivileged(new PrivilegedAction<Void>() {
 599             public Void run() {
 600 
 601                 ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
 602                 Iterator<Driver> driversIterator = loadedDrivers.iterator();
 603 
 604                 /* Load these drivers, so that they can be instantiated.
 605                  * It may be the case that the driver class may not be there
 606                  * i.e. there may be a packaged driver with the service class
 607                  * as implementation of java.sql.Driver but the actual class
 608                  * may be missing. In that case a java.util.ServiceConfigurationError
 609                  * will be thrown at runtime by the VM trying to locate


 623                 return null;
 624             }
 625         });
 626 
 627         println("DriverManager.initialize: jdbc.drivers = " + drivers);
 628 
 629         if (drivers == null || drivers.equals("")) {
 630             return;
 631         }
 632         String[] driversList = drivers.split(":");
 633         println("number of Drivers:" + driversList.length);
 634         for (String aDriver : driversList) {
 635             try {
 636                 println("DriverManager.Initialize: loading " + aDriver);
 637                 Class.forName(aDriver, true,
 638                         ClassLoader.getSystemClassLoader());
 639             } catch (Exception ex) {
 640                 println("DriverManager.Initialize: load failed: " + ex);
 641             }
 642         }
 643 
 644         driversInitialized = true;
 645         println("JDBC DriverManager initialized");
 646     }
 647 
 648 
 649     //  Worker method called by the public getConnection() methods.
 650     private static Connection getConnection(
 651         String url, java.util.Properties info, Class<?> caller) throws SQLException {
 652         /*
 653          * When callerCl is null, we should check the application's
 654          * (which is invoking this class indirectly)
 655          * classloader, so that the JDBC driver class outside rt.jar
 656          * can be loaded from here.
 657          */
 658         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
 659         if(callerCL == null) {


 660             callerCL = Thread.currentThread().getContextClassLoader();
 661         }

 662 
 663         if(url == null) {
 664             throw new SQLException("The url cannot be null", "08001");
 665         }
 666 
 667         println("DriverManager.getConnection(\"" + url + "\")");
 668         
 669         // Walk through the loaded registeredDrivers attempting to make a connection.
 670         // Remember the first exception that gets raised so we can reraise it.
 671         SQLException reason = null;
 672 
 673         for(DriverInfo aDriver : getRegisteredDrivers()) {
 674             // If the caller does not have permission to load the driver then
 675             // skip it.
 676             if(isDriverAllowed(aDriver.driver, callerCL)) {
 677                 try {
 678                     println("    trying " + aDriver.driver.getClass().getName());
 679                     Connection con = aDriver.driver.connect(url, info);
 680                     if (con != null) {
 681                         // Success!
 682                         println("getConnection returning " + aDriver.driver.getClass().getName());
 683                         return (con);
 684                     }
 685                 } catch (SQLException ex) {
 686                     if (reason == null) {
 687                         reason = ex;
 688                     }
 689                 }
 690 
 691             } else {
 692                 println("    skipping: " + aDriver.getClass().getName());
 693             }