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 ----