jdk/src/share/classes/java/sql/DriverManager.java
changeset 16906 44dfee24cb71
parent 16887 b7c122a88eed
child 17199 28853592ce2b
equal deleted inserted replaced
16905:0419f45c7761 16906:44dfee24cb71
    28 import java.util.Iterator;
    28 import java.util.Iterator;
    29 import java.util.ServiceLoader;
    29 import java.util.ServiceLoader;
    30 import java.security.AccessController;
    30 import java.security.AccessController;
    31 import java.security.PrivilegedAction;
    31 import java.security.PrivilegedAction;
    32 import java.util.concurrent.CopyOnWriteArrayList;
    32 import java.util.concurrent.CopyOnWriteArrayList;
       
    33 import sun.reflect.CallerSensitive;
    33 import sun.reflect.Reflection;
    34 import sun.reflect.Reflection;
    34 
    35 
    35 
    36 
    36 /**
    37 /**
    37  * <P>The basic service for managing a set of JDBC drivers.<br>
    38  * <P>The basic service for managing a set of JDBC drivers.<br>
   190      * @throws SQLTimeoutException  when the driver has determined that the
   191      * @throws SQLTimeoutException  when the driver has determined that the
   191      * timeout value specified by the {@code setLoginTimeout} method
   192      * timeout value specified by the {@code setLoginTimeout} method
   192      * has been exceeded and has at least tried to cancel the
   193      * has been exceeded and has at least tried to cancel the
   193      * current database connection attempt
   194      * current database connection attempt
   194      */
   195      */
       
   196     @CallerSensitive
   195     public static Connection getConnection(String url,
   197     public static Connection getConnection(String url,
   196         java.util.Properties info) throws SQLException {
   198         java.util.Properties info) throws SQLException {
   197 
   199 
   198         // Gets the classloader of the code that called this method, may
   200         return (getConnection(url, info, Reflection.getCallerClass()));
   199         // be null.
       
   200         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   201 
       
   202         return (getConnection(url, info, callerCL));
       
   203     }
   201     }
   204 
   202 
   205     /**
   203     /**
   206      * Attempts to establish a connection to the given database URL.
   204      * Attempts to establish a connection to the given database URL.
   207      * The <code>DriverManager</code> attempts to select an appropriate driver from
   205      * The <code>DriverManager</code> attempts to select an appropriate driver from
   224      * @throws SQLTimeoutException  when the driver has determined that the
   222      * @throws SQLTimeoutException  when the driver has determined that the
   225      * timeout value specified by the {@code setLoginTimeout} method
   223      * timeout value specified by the {@code setLoginTimeout} method
   226      * has been exceeded and has at least tried to cancel the
   224      * has been exceeded and has at least tried to cancel the
   227      * current database connection attempt
   225      * current database connection attempt
   228      */
   226      */
       
   227     @CallerSensitive
   229     public static Connection getConnection(String url,
   228     public static Connection getConnection(String url,
   230         String user, String password) throws SQLException {
   229         String user, String password) throws SQLException {
   231         java.util.Properties info = new java.util.Properties();
   230         java.util.Properties info = new java.util.Properties();
   232 
   231 
   233         // Gets the classloader of the code that called this method, may
       
   234         // be null.
       
   235         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   236 
       
   237         if (user != null) {
   232         if (user != null) {
   238             info.put("user", user);
   233             info.put("user", user);
   239         }
   234         }
   240         if (password != null) {
   235         if (password != null) {
   241             info.put("password", password);
   236             info.put("password", password);
   242         }
   237         }
   243 
   238 
   244         return (getConnection(url, info, callerCL));
   239         return (getConnection(url, info, Reflection.getCallerClass()));
   245     }
   240     }
   246 
   241 
   247     /**
   242     /**
   248      * Attempts to establish a connection to the given database URL.
   243      * Attempts to establish a connection to the given database URL.
   249      * The <code>DriverManager</code> attempts to select an appropriate driver from
   244      * The <code>DriverManager</code> attempts to select an appropriate driver from
   257      * @throws SQLTimeoutException  when the driver has determined that the
   252      * @throws SQLTimeoutException  when the driver has determined that the
   258      * timeout value specified by the {@code setLoginTimeout} method
   253      * timeout value specified by the {@code setLoginTimeout} method
   259      * has been exceeded and has at least tried to cancel the
   254      * has been exceeded and has at least tried to cancel the
   260      * current database connection attempt
   255      * current database connection attempt
   261      */
   256      */
       
   257     @CallerSensitive
   262     public static Connection getConnection(String url)
   258     public static Connection getConnection(String url)
   263         throws SQLException {
   259         throws SQLException {
   264 
   260 
   265         java.util.Properties info = new java.util.Properties();
   261         java.util.Properties info = new java.util.Properties();
   266 
   262         return (getConnection(url, info, Reflection.getCallerClass()));
   267         // Gets the classloader of the code that called this method, may
       
   268         // be null.
       
   269         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   270 
       
   271         return (getConnection(url, info, callerCL));
       
   272     }
   263     }
   273 
   264 
   274     /**
   265     /**
   275      * Attempts to locate a driver that understands the given URL.
   266      * Attempts to locate a driver that understands the given URL.
   276      * The <code>DriverManager</code> attempts to select an appropriate driver from
   267      * The <code>DriverManager</code> attempts to select an appropriate driver from
   280      *     <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
   271      *     <code>jdbc:<em>subprotocol</em>:<em>subname</em></code>
   281      * @return a <code>Driver</code> object representing a driver
   272      * @return a <code>Driver</code> object representing a driver
   282      * that can connect to the given URL
   273      * that can connect to the given URL
   283      * @exception SQLException if a database access error occurs
   274      * @exception SQLException if a database access error occurs
   284      */
   275      */
       
   276     @CallerSensitive
   285     public static Driver getDriver(String url)
   277     public static Driver getDriver(String url)
   286         throws SQLException {
   278         throws SQLException {
   287 
   279 
   288         println("DriverManager.getDriver(\"" + url + "\")");
   280         println("DriverManager.getDriver(\"" + url + "\")");
   289 
   281 
   290         // Gets the classloader of the code that called this method, may
   282         Class<?> callerClass = Reflection.getCallerClass();
   291         // be null.
       
   292         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   293 
   283 
   294         // Walk through the loaded registeredDrivers attempting to locate someone
   284         // Walk through the loaded registeredDrivers attempting to locate someone
   295         // who understands the given URL.
   285         // who understands the given URL.
   296         for (DriverInfo aDriver : registeredDrivers) {
   286         for (DriverInfo aDriver : registeredDrivers) {
   297             // If the caller does not have permission to load the driver then
   287             // If the caller does not have permission to load the driver then
   298             // skip it.
   288             // skip it.
   299             if(isDriverAllowed(aDriver.driver, callerCL)) {
   289             if(isDriverAllowed(aDriver.driver, callerClass)) {
   300                 try {
   290                 try {
   301                     if(aDriver.driver.acceptsURL(url)) {
   291                     if(aDriver.driver.acceptsURL(url)) {
   302                         // Success!
   292                         // Success!
   303                         println("getDriver returning " + aDriver.driver.getClass().getName());
   293                         println("getDriver returning " + aDriver.driver.getClass().getName());
   304                     return (aDriver.driver);
   294                     return (aDriver.driver);
   348      *  Applets can only deregister drivers from their own classloaders.
   338      *  Applets can only deregister drivers from their own classloaders.
   349      *
   339      *
   350      * @param driver the JDBC Driver to drop
   340      * @param driver the JDBC Driver to drop
   351      * @exception SQLException if a database access error occurs
   341      * @exception SQLException if a database access error occurs
   352      */
   342      */
       
   343     @CallerSensitive
   353     public static synchronized void deregisterDriver(Driver driver)
   344     public static synchronized void deregisterDriver(Driver driver)
   354         throws SQLException {
   345         throws SQLException {
   355         if (driver == null) {
   346         if (driver == null) {
   356             return;
   347             return;
   357         }
   348         }
   358 
   349 
   359         // Gets the classloader of the code that called this method,
       
   360         // may be null.
       
   361         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   362         println("DriverManager.deregisterDriver: " + driver);
   350         println("DriverManager.deregisterDriver: " + driver);
   363 
   351 
   364         DriverInfo aDriver = new DriverInfo(driver);
   352         DriverInfo aDriver = new DriverInfo(driver);
   365         if(registeredDrivers.contains(aDriver)) {
   353         if(registeredDrivers.contains(aDriver)) {
   366             if (isDriverAllowed(driver, callerCL)) {
   354             if (isDriverAllowed(driver, Reflection.getCallerClass())) {
   367                  registeredDrivers.remove(aDriver);
   355                  registeredDrivers.remove(aDriver);
   368             } else {
   356             } else {
   369                 // If the caller does not have permission to load the driver then
   357                 // If the caller does not have permission to load the driver then
   370                 // throw a SecurityException.
   358                 // throw a SecurityException.
   371                 throw new SecurityException();
   359                 throw new SecurityException();
   382      * <P><B>Note:</B> The classname of a driver can be found using
   370      * <P><B>Note:</B> The classname of a driver can be found using
   383      * <CODE>d.getClass().getName()</CODE>
   371      * <CODE>d.getClass().getName()</CODE>
   384      *
   372      *
   385      * @return the list of JDBC Drivers loaded by the caller's class loader
   373      * @return the list of JDBC Drivers loaded by the caller's class loader
   386      */
   374      */
       
   375     @CallerSensitive
   387     public static java.util.Enumeration<Driver> getDrivers() {
   376     public static java.util.Enumeration<Driver> getDrivers() {
   388         java.util.Vector<Driver> result = new java.util.Vector<>();
   377         java.util.Vector<Driver> result = new java.util.Vector<>();
   389 
   378 
   390         // Gets the classloader of the code that called this method, may
   379         Class<?> callerClass = Reflection.getCallerClass();
   391         // be null.
       
   392         ClassLoader callerCL = DriverManager.getCallerClassLoader();
       
   393 
   380 
   394         // Walk through the loaded registeredDrivers.
   381         // Walk through the loaded registeredDrivers.
   395         for(DriverInfo aDriver : registeredDrivers) {
   382         for(DriverInfo aDriver : registeredDrivers) {
   396             // If the caller does not have permission to load the driver then
   383             // If the caller does not have permission to load the driver then
   397             // skip it.
   384             // skip it.
   398             if(isDriverAllowed(aDriver.driver, callerCL)) {
   385             if(isDriverAllowed(aDriver.driver, callerClass)) {
   399                 result.addElement(aDriver.driver);
   386                 result.addElement(aDriver.driver);
   400             } else {
   387             } else {
   401                 println("    skipping: " + aDriver.getClass().getName());
   388                 println("    skipping: " + aDriver.getClass().getName());
   402             }
   389             }
   403         }
   390         }
   491         }
   478         }
   492     }
   479     }
   493 
   480 
   494     //------------------------------------------------------------------------
   481     //------------------------------------------------------------------------
   495 
   482 
   496     // Internal method used to get the caller's class loader.
       
   497     // Replaces the call to the native method
       
   498     private static ClassLoader getCallerClassLoader() {
       
   499         Class<?> cc = Reflection.getCallerClass(3);
       
   500         ClassLoader cl = (cc != null) ? cc.getClassLoader() : null;
       
   501         return cl;
       
   502     }
       
   503 
       
   504 
       
   505     // Indicates whether the class object that would be created if the code calling
   483     // Indicates whether the class object that would be created if the code calling
   506     // DriverManager is accessible.
   484     // DriverManager is accessible.
       
   485     private static boolean isDriverAllowed(Driver driver, Class<?> caller) {
       
   486         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
       
   487         return isDriverAllowed(driver, callerCL);
       
   488     }
       
   489 
   507     private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
   490     private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
   508         boolean result = false;
   491         boolean result = false;
   509         if(driver != null) {
   492         if(driver != null) {
   510             Class<?> aClass = null;
   493             Class<?> aClass = null;
   511             try {
   494             try {
   584     }
   567     }
   585 
   568 
   586 
   569 
   587     //  Worker method called by the public getConnection() methods.
   570     //  Worker method called by the public getConnection() methods.
   588     private static Connection getConnection(
   571     private static Connection getConnection(
   589         String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
   572         String url, java.util.Properties info, Class<?> caller) throws SQLException {
   590         /*
   573         /*
   591          * When callerCl is null, we should check the application's
   574          * When callerCl is null, we should check the application's
   592          * (which is invoking this class indirectly)
   575          * (which is invoking this class indirectly)
   593          * classloader, so that the JDBC driver class outside rt.jar
   576          * classloader, so that the JDBC driver class outside rt.jar
   594          * can be loaded from here.
   577          * can be loaded from here.
   595          */
   578          */
       
   579         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
   596         synchronized(DriverManager.class) {
   580         synchronized(DriverManager.class) {
   597           // synchronize loading of the correct classloader.
   581             // synchronize loading of the correct classloader.
   598           if(callerCL == null) {
   582             if (callerCL == null) {
   599               callerCL = Thread.currentThread().getContextClassLoader();
   583                 callerCL = Thread.currentThread().getContextClassLoader();
   600            }
   584             }
   601         }
   585         }
   602 
   586 
   603         if(url == null) {
   587         if(url == null) {
   604             throw new SQLException("The url cannot be null", "08001");
   588             throw new SQLException("The url cannot be null", "08001");
   605         }
   589         }