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

Print this page

        

@@ -27,10 +27,11 @@
 
 import java.util.Iterator;
 import java.util.ServiceLoader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.PropertyPermission;
 import java.util.concurrent.CopyOnWriteArrayList;
 import sun.reflect.CallerSensitive;
 import sun.reflect.Reflection;
 
 

@@ -86,24 +87,16 @@
     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 final static  Object logSync = new Object();
+    private static volatile boolean driversInitialized;
+    private static final String JDBC_DRIVERS_PROPERTY = "jdbc.drivers";
 
     /* Prevent the DriverManager class from being instantiated. */
     private DriverManager(){}
 
-
-    /**
-     * 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
      */

@@ -289,11 +282,11 @@
 
         Class<?> callerClass = Reflection.getCallerClass();
 
         // Walk through the loaded registeredDrivers attempting to locate someone
         // who understands the given URL.
-        for (DriverInfo aDriver : registeredDrivers) {
+        for (DriverInfo aDriver : getRegisteredDrivers()) {
             // If the caller does not have permission to load the driver then
             // skip it.
             if(isDriverAllowed(aDriver.driver, callerClass)) {
                 try {
                     if(aDriver.driver.acceptsURL(url)) {

@@ -326,11 +319,11 @@
      * @param driver the new JDBC Driver that is to be registered with the
      *               {@code DriverManager}
      * @exception SQLException if a database access error occurs
      * @exception NullPointerException if {@code driver} is null
      */
-    public static synchronized void registerDriver(java.sql.Driver driver)
+    public static void registerDriver(java.sql.Driver driver)
         throws SQLException {
 
         registerDriver(driver, null);
     }
 

@@ -347,11 +340,11 @@
      *               {@code DriverManager#deregisterDriver} is called
      * @exception SQLException if a database access error occurs
      * @exception NullPointerException if {@code driver} is null
      * @since 1.8
      */
-    public static synchronized void registerDriver(java.sql.Driver driver,
+    public static void registerDriver(java.sql.Driver driver,
             DriverAction da)
         throws SQLException {
 
         /* Register the driver if it has not already been added to our list */
         if(driver != null) {

@@ -438,11 +431,11 @@
         java.util.Vector<Driver> result = new java.util.Vector<>();
 
         Class<?> callerClass = Reflection.getCallerClass();
 
         // Walk through the loaded registeredDrivers.
-        for(DriverInfo aDriver : registeredDrivers) {
+        for(DriverInfo aDriver : getRegisteredDrivers()) {
             // If the caller does not have permission to load the driver then
             // skip it.
             if(isDriverAllowed(aDriver.driver, callerClass)) {
                 result.addElement(aDriver.driver);
             } else {

@@ -562,18 +555,40 @@
         }
 
         return result;
     }
 
-    private static void loadInitialDrivers() {
+    /*
+     * Return the registered java.sql.Drivers and call loadInitialDrivers
+     * if needed
+     */
+    private static CopyOnWriteArrayList<DriverInfo> getRegisteredDrivers() {
+        // Check to see if we need to load the initial drivers
+        if (!driversInitialized) {
+            loadInitialDrivers();
+        }
+        return registeredDrivers;
+
+    }
+
+    /*
+     * Load the initial JDBC drivers by checking the System property
+     * jdbc.properties and then use the {@code ServiceLoader} mechanism
+     */
+    private synchronized static void loadInitialDrivers() {
         String drivers;
+
+        if (driversInitialized) {
+            return;
+        }
+        
         try {
             drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
                 public String run() {
-                    return System.getProperty("jdbc.drivers");
+                    return System.getProperty(JDBC_DRIVERS_PROPERTY);
                 }
-            });
+            }, null, new PropertyPermission(JDBC_DRIVERS_PROPERTY, "read"));
         } catch (Exception ex) {
             drivers = null;
         }
         // If the driver is packaged as a Service Provider, load it.
         // Get all the drivers through the classloader

@@ -623,10 +638,13 @@
                         ClassLoader.getSystemClassLoader());
             } catch (Exception ex) {
                 println("DriverManager.Initialize: load failed: " + ex);
             }
         }
+
+        driversInitialized = true;
+        println("JDBC DriverManager initialized");
     }
 
 
     //  Worker method called by the public getConnection() methods.
     private static Connection getConnection(

@@ -636,16 +654,13 @@
          * (which is invoking this class indirectly)
          * classloader, so that the JDBC driver class outside rt.jar
          * can be loaded from here.
          */
         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
-        synchronized(DriverManager.class) {
-            // synchronize loading of the correct classloader.
-            if (callerCL == null) {
+        if(callerCL == null) {
                 callerCL = Thread.currentThread().getContextClassLoader();
             }
-        }
 
         if(url == null) {
             throw new SQLException("The url cannot be null", "08001");
         }
 

@@ -653,11 +668,11 @@
 
         // 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(DriverInfo aDriver : registeredDrivers) {
+        for(DriverInfo aDriver : getRegisteredDrivers()) {
             // If the caller does not have permission to load the driver then
             // skip it.
             if(isDriverAllowed(aDriver.driver, callerCL)) {
                 try {
                     println("    trying " + aDriver.driver.getClass().getName());