--- old/src/share/classes/java/sql/DriverManager.java 2013-04-19 12:54:16.000000000 -0400 +++ new/src/share/classes/java/sql/DriverManager.java 2013-04-19 12:54:16.000000000 -0400 @@ -108,6 +108,14 @@ */ final static SQLPermission SET_LOG_PERMISSION = new SQLPermission("setLog"); + + /** + * The {@code SQLPermission} constant that allows the + * un-register a registered JDBC driver. + * @since 1.8 + */ + final static SQLPermission DEREGISTER_DRIVER_PERMISSION = + new SQLPermission("deregisterDriver"); //--------------------------JDBC 2.0----------------------------- @@ -331,9 +339,33 @@ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { + registerDriver(driver, null); + } + + /** + * Registers the given driver with the DriverManager. + * A newly-loaded driver class should call + * the method {@code registerDriver} to make itself + * known to the {@code DriverManager}. + * + * @param driver the new JDBC Driver that is to be registered with the + * {@code DriverManager} + * @param da the {@code DriverAction} implementation to be called + * when the JDBC Driver has been de-registered; or null if the JDBC + * driver is not to be notified when de-registered. + * @exception SQLException if a database access error occurs + * @see DriverAction + * @since 1.8 + */ + public static synchronized 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) { - registeredDrivers.addIfAbsent(new DriverInfo(driver)); + DriverInfo di = new DriverInfo(driver); + di.da= da; + registeredDrivers.addIfAbsent(di); } else { // This is for compatibility with the original DriverManager throw new NullPointerException(); @@ -343,19 +375,38 @@ } - /** - * Drops a driver from the DriverManager's list. - * Applets can only deregister drivers from their own classloaders. + /** + * Removes the specified driver from the {@code DriverManager}'s list of + * registered drivers. + *

+ * If a security manager exists and its {@code checkPermission} denies + * permission, then a {@code SecurityException} will be thrown. + *

+ * No action will be taken if the specified driver + * was not found in the list of registered drivers or was {@code null}. + *

+ * If a {@code DriverAction} implementation was specified when the driver was + * registered, its {@code deregister} method will be called. * - * @param driver the JDBC Driver to drop + * @param driver the JDBC Driver to remove * @exception SQLException if a database access error occurs + * @throws SecurityException if a security manager exists and its + * {@code checkPermission} method denies permission to deregister a driver. + * + * @see SecurityManager#checkPermission + * @see DriverAction */ public static synchronized void deregisterDriver(Driver driver) throws SQLException { if (driver == null) { return; } - + + SecurityManager sec = System.getSecurityManager(); + if (sec != null) { + sec.checkPermission(DEREGISTER_DRIVER_PERMISSION); + } + // Gets the classloader of the code that called this method, // may be null. ClassLoader callerCL = DriverManager.getCallerClassLoader(); @@ -364,11 +415,13 @@ DriverInfo aDriver = new DriverInfo(driver); if(registeredDrivers.contains(aDriver)) { if (isDriverAllowed(driver, callerCL)) { + DriverInfo di = registeredDrivers.get(registeredDrivers.indexOf(aDriver)); + // If a DriverAction was specified, Call it to notify the + // driver that it has been deregistered + if(di.da != null) { + di.da.deregister(); + } registeredDrivers.remove(aDriver); - } 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"); @@ -655,10 +708,12 @@ class DriverInfo { final Driver driver; - DriverInfo(Driver driver) { + DriverAction da; + DriverInfo(Driver driver) { this.driver = driver; + da = null; } - + @Override public boolean equals(Object other) { return (other instanceof DriverInfo)