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

Print this page

        

*** 24,37 **** */ package java.sql; import java.util.Iterator; - import java.sql.Driver; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; /** * <P>The basic service for managing a set of JDBC drivers.<br> * <B>NOTE:</B> The {@link <code>DataSource</code>} interface, new in the --- 24,37 ---- */ package java.sql; import java.util.Iterator; import java.util.ServiceLoader; import java.security.AccessController; import java.security.PrivilegedAction; + import java.util.concurrent.CopyOnWriteArrayList; /** * <P>The basic service for managing a set of JDBC drivers.<br> * <B>NOTE:</B> The {@link <code>DataSource</code>} interface, new in the
*** 77,86 **** --- 77,103 ---- * @see Connection */ public class DriverManager { + // List of registered JDBC drivers + private final static CopyOnWriteArrayList<Driver> registeredDrivers = new CopyOnWriteArrayList<Driver>(); + private static volatile int loginTimeout = 0; + private static volatile java.io.PrintWriter logWriter = null; + private static volatile java.io.PrintStream logStream = null; + // Used in println() to synchronize logWriter + private static Object logSync = new Object(); + + /** + * Load the initial JDBC drivers by checking the System property + * jdbc.properties and then use the {@code ServiceLoader} mechanism + */ + static { + loadInitialDrivers(); + println("JDBC DriverManager initialized"); + } + /** * The <code>SQLPermission</code> constant that allows the * setting of the logging stream. * @since 1.3 */
*** 233,280 **** * that can connect to the given URL * @exception SQLException if a database access error occurs */ public static Driver getDriver(String url) throws SQLException { - java.util.Vector drivers = null; println("DriverManager.getDriver(\"" + url + "\")"); - if (!initialized) { - initialize(); - } - - synchronized (DriverManager.class){ - // use the read copy of the drivers vector - drivers = readDrivers; - } - // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); ! // Walk through the loaded drivers attempting to locate someone // who understands the given URL. ! for (int i = 0; i < drivers.size(); i++) { ! DriverInfo di = (DriverInfo)drivers.elementAt(i); // If the caller does not have permission to load the driver then // skip it. ! if ( getCallerClass(callerCL, di.driverClassName ) != ! di.driverClass ) { ! println(" skipping: " + di); ! continue; ! } try { ! println(" trying " + di); ! if (di.driver.acceptsURL(url)) { // Success! ! println("getDriver returning " + di); ! return (di.driver); } ! } catch (SQLException ex) { // Drop through and try the next driver. } } println("getDriver: no suitable driver"); throw new SQLException("No suitable driver", "08001"); } --- 250,286 ---- * that can connect to the given URL * @exception SQLException if a database access error occurs */ public static Driver getDriver(String url) throws SQLException { println("DriverManager.getDriver(\"" + url + "\")"); // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); ! // Walk through the loaded registeredDrivers attempting to locate someone // who understands the given URL. ! for (Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. ! if(isDriverAllowed(aDriver, callerCL)) { try { ! if(aDriver.acceptsURL(url)) { // Success! ! println("getDriver returning " + aDriver.getClass().getName()); ! return (aDriver); } ! ! } catch(SQLException sqe) { // Drop through and try the next driver. } + } else { + println(" skipping: " + aDriver.getClass().getName()); + } + } println("getDriver: no suitable driver"); throw new SQLException("No suitable driver", "08001"); }
*** 290,316 **** * <code>DriverManager</code> * @exception SQLException if a database access error occurs */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { - if (!initialized) { - initialize(); - } - - DriverInfo di = new DriverInfo(); ! di.driver = driver; ! di.driverClass = driver.getClass(); ! di.driverClassName = di.driverClass.getName(); ! ! // Not Required -- drivers.addElement(di); ! ! writeDrivers.addElement(di); ! println("registerDriver: " + di); ! /* update the read copy of drivers vector */ ! readDrivers = (java.util.Vector) writeDrivers.clone(); } /** * Drops a driver from the <code>DriverManager</code>'s list. --- 296,315 ---- * <code>DriverManager</code> * @exception SQLException if a database access error occurs */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { ! /* Register the driver if it has not already been added to our list */ ! if(driver != null) { ! registeredDrivers.addIfAbsent(driver); ! } else { ! // This is for compatibility with the original DriverManager ! throw new NullPointerException(); ! } ! println("registerDriver: " + driver); } /** * Drops a driver from the <code>DriverManager</code>'s list.
*** 319,359 **** * @param driver the JDBC Driver to drop * @exception SQLException if a database access error occurs */ public static synchronized void deregisterDriver(Driver driver) throws SQLException { // Gets the classloader of the code that called this method, // may be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); println("DriverManager.deregisterDriver: " + driver); ! // Walk through the loaded drivers. ! int i; ! DriverInfo di = null; ! for (i = 0; i < writeDrivers.size(); i++) { ! di = (DriverInfo)writeDrivers.elementAt(i); ! if (di.driver == driver) { ! break; ! } ! } ! // If we can't find the driver just return. ! if (i >= writeDrivers.size()) { ! println(" couldn't find driver to unload"); ! return; ! } ! // If the caller does not have permission to load the driver then ! // throw a security exception. ! if (getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { throw new SecurityException(); } ! ! // Remove the driver. Other entries in drivers get shuffled down. ! writeDrivers.removeElementAt(i); ! ! /* update the read copy of drivers vector */ ! readDrivers = (java.util.Vector) writeDrivers.clone(); } /** * Retrieves an Enumeration with all of the currently loaded JDBC drivers * to which the current caller has access. --- 318,347 ---- * @param driver the JDBC Driver to drop * @exception SQLException if a database access error occurs */ public static synchronized void deregisterDriver(Driver driver) throws SQLException { + if (driver == null) { + return; + } + // Gets the classloader of the code that called this method, // may be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); println("DriverManager.deregisterDriver: " + driver); ! if(registeredDrivers.contains(driver)) { ! if (isDriverAllowed(driver, callerCL)) { ! registeredDrivers.remove(driver); ! } else { // If the caller does not have permission to load the driver then ! // throw a SecurityException. throw new SecurityException(); } ! } else { ! println(" couldn't find driver to unload"); ! } } /** * Retrieves an Enumeration with all of the currently loaded JDBC drivers * to which the current caller has access.
*** 362,399 **** * <CODE>d.getClass().getName()</CODE> * * @return the list of JDBC Drivers loaded by the caller's class loader */ public static java.util.Enumeration<Driver> getDrivers() { ! java.util.Vector<Driver> result = new java.util.Vector<>(); ! java.util.Vector drivers = null; ! ! if (!initialized) { ! initialize(); ! } ! ! synchronized (DriverManager.class){ ! // use the readcopy of drivers ! drivers = readDrivers; ! } // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); ! // Walk through the loaded drivers. ! for (int i = 0; i < drivers.size(); i++) { ! DriverInfo di = (DriverInfo)drivers.elementAt(i); // If the caller does not have permission to load the driver then // skip it. ! if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { ! println(" skipping: " + di); ! continue; } - result.addElement(di.driver); } - return (result.elements()); } /** --- 350,375 ---- * <CODE>d.getClass().getName()</CODE> * * @return the list of JDBC Drivers loaded by the caller's class loader */ public static java.util.Enumeration<Driver> getDrivers() { ! java.util.Vector<Driver> result = new java.util.Vector<Driver>(); // Gets the classloader of the code that called this method, may // be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); ! // Walk through the loaded registeredDrivers. ! for(Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. ! if(isDriverAllowed(aDriver, callerCL)) { ! result.addElement(aDriver); ! } else { ! println(" skipping: " + aDriver.getClass().getName()); } } return (result.elements()); } /**
*** 479,503 **** } } //------------------------------------------------------------------------ ! // Returns the class object that would be created if the code calling the ! // driver manager had loaded the driver class, or null if the class ! // is inaccessible. ! private static Class getCallerClass(ClassLoader callerClassLoader, ! String driverClassName) { ! Class callerC = null; ! try { ! callerC = Class.forName(driverClassName, true, callerClassLoader); } ! catch (Exception ex) { ! callerC = null; // being very careful } ! return callerC; } private static void loadInitialDrivers() { String drivers; try { --- 455,480 ---- } } //------------------------------------------------------------------------ ! // Indicates whether the class object that would be created if the code calling ! // DriverManager is accessible. ! private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { ! boolean result = false; ! if(driver != null) { ! Class<?> aClass = null; try { ! aClass = Class.forName(driver.getClass().getName(), true, classLoader); ! } catch (Exception ex) { ! result = false; } ! ! result = ( aClass == driver.getClass() ) ? true : false; } ! return result; } private static void loadInitialDrivers() { String drivers; try {
*** 542,570 **** return null; } }); println("DriverManager.initialize: jdbc.drivers = " + drivers); ! if (drivers == null) { return; } ! while (drivers.length() != 0) { ! int x = drivers.indexOf(':'); ! String driver; ! if (x < 0) { ! driver = drivers; ! drivers = ""; ! } else { ! driver = drivers.substring(0, x); ! drivers = drivers.substring(x+1); ! } ! if (driver.length() == 0) { ! continue; ! } try { ! println("DriverManager.Initialize: loading " + driver); ! Class.forName(driver, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } } --- 519,538 ---- return null; } }); println("DriverManager.initialize: jdbc.drivers = " + drivers); ! ! if (drivers == null || drivers.equals("")) { return; } ! String[] driversList = drivers.split(":"); ! println("number of Drivers:" + driversList.length); ! for (String aDriver : driversList) { try { ! println("DriverManager.Initialize: loading " + aDriver); ! Class.forName(aDriver, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } }
*** 572,582 **** // Worker method called by the public getConnection() methods. private static Connection getConnection( String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { - java.util.Vector drivers = null; /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. --- 540,549 ----
*** 592,635 **** throw new SQLException("The url cannot be null", "08001"); } println("DriverManager.getConnection(\"" + url + "\")"); ! if (!initialized) { ! initialize(); ! } ! ! synchronized (DriverManager.class){ ! // use the readcopy of drivers ! drivers = readDrivers; ! } ! ! // Walk through the loaded drivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; - for (int i = 0; i < drivers.size(); i++) { - DriverInfo di = (DriverInfo)drivers.elementAt(i); // If the caller does not have permission to load the driver then // skip it. ! if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { ! println(" skipping: " + di); ! continue; ! } try { ! println(" trying " + di); ! Connection result = di.driver.connect(url, info); ! if (result != null) { // Success! ! println("getConnection returning " + di); ! return (result); } } catch (SQLException ex) { if (reason == null) { reason = ex; } } } // if we got here nobody could connect. if (reason != null) { println("getConnection failed: " + reason); --- 559,594 ---- throw new SQLException("The url cannot be null", "08001"); } println("DriverManager.getConnection(\"" + url + "\")"); ! // Walk through the loaded registeredDrivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; + for(Driver aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. ! if(isDriverAllowed(aDriver, callerCL)) { try { ! println(" trying " + aDriver.getClass().getName()); ! Connection con = aDriver.connect(url, info); ! if (con != null) { // Success! ! println("getConnection returning " + aDriver.getClass().getName()); ! return (con); } } catch (SQLException ex) { if (reason == null) { reason = ex; } } + + } else { + println(" skipping: " + aDriver.getClass().getName()); + } + } // if we got here nobody could connect. if (reason != null) { println("getConnection failed: " + reason);
*** 638,684 **** println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); } - - // Class initialization. - static void initialize() { - if (initialized) { - return; - } - initialized = true; - loadInitialDrivers(); - println("JDBC DriverManager initialized"); - } - /* Prevent the DriverManager class from being instantiated. */ private DriverManager(){} - /* write copy of the drivers vector */ - private static java.util.Vector writeDrivers = new java.util.Vector(); - - /* write copy of the drivers vector */ - private static java.util.Vector readDrivers = new java.util.Vector(); - - private static int loginTimeout = 0; - private static java.io.PrintWriter logWriter = null; - private static java.io.PrintStream logStream = null; - private static boolean initialized = false; - - private static Object logSync = new Object(); - /* Returns the caller's class loader, or null if none */ private static native ClassLoader getCallerClassLoader(); } - - // DriverInfo is a package-private support class. - class DriverInfo { - Driver driver; - Class driverClass; - String driverClassName; - - public String toString() { - return ("driver[className=" + driverClassName + "," + driver + "]"); - } - } --- 597,608 ----