8010416: Add a way for java.sql.Driver to be notified when it is deregistered
Reviewed-by: alanb, ulfzibis
This commit is contained in:
parent
8394ed673f
commit
785f0d2a94
@ -44,13 +44,16 @@ import java.util.logging.Logger;
|
||||
*
|
||||
* <P>When a Driver class is loaded, it should create an instance of
|
||||
* itself and register it with the DriverManager. This means that a
|
||||
* user can load and register a driver by calling
|
||||
* <pre>
|
||||
* <code>Class.forName("foo.bah.Driver")</code>
|
||||
* </pre>
|
||||
*
|
||||
* user can load and register a driver by calling:
|
||||
* <p>
|
||||
* {@code Class.forName("foo.bah.Driver")}
|
||||
* <p>
|
||||
* A JDBC driver may create a {@linkplain DriverAction} implementation in order
|
||||
* to receive notifications when {@linkplain DriverManager#deregisterDriver} has
|
||||
* been called.
|
||||
* @see DriverManager
|
||||
* @see Connection
|
||||
* @see DriverAction
|
||||
*/
|
||||
public interface Driver {
|
||||
|
||||
|
66
jdk/src/share/classes/java/sql/DriverAction.java
Normal file
66
jdk/src/share/classes/java/sql/DriverAction.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.sql;
|
||||
|
||||
/**
|
||||
* An interface that must be implemented when a {@linkplain Driver} wants to be
|
||||
* notified by {@code DriverManager}.
|
||||
*<P>
|
||||
* A {@code DriverAction} implementation is not intended to be used
|
||||
* directly by applications. A JDBC Driver may choose
|
||||
* to create its {@code DriverAction} implementation in a private class
|
||||
* to avoid it being called directly.
|
||||
* <o>
|
||||
* The JDBC driver's static initialization block must call
|
||||
* {@linkplain DriverManager#registerDriver(java.sql.Driver, java.sql.DriverAction) } in order
|
||||
* to inform {@code DriverManager} which {@code DriverAction} implementation to
|
||||
* call when the JDBC driver is de-registered.
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface DriverAction {
|
||||
/**
|
||||
* Method called by
|
||||
* {@linkplain DriverManager#deregisterDriver(Driver) }
|
||||
* to notify the JDBC driver that it was de-registered.
|
||||
* <p>
|
||||
* The {@code deregister} method is intended only to be used by JDBC Drivers
|
||||
* and not by applications. JDBC drivers are recommended to not implement
|
||||
* {@code DriverAction} in a public class. If there are active
|
||||
* connections to the database at the time that the {@code deregister}
|
||||
* method is called, it is implementation specific as to whether the
|
||||
* connections are closed or allowed to continue. Once this method is
|
||||
* called, it is implementation specific as to whether the driver may
|
||||
* limit the ability to create new connections to the database, invoke
|
||||
* other {@code Driver} methods or throw a {@code SQLException}.
|
||||
* Consult your JDBC driver's documentation for additional information
|
||||
* on its behavior.
|
||||
* @see DriverManager#registerDriver(java.sql.Driver, java.sql.DriverAction)
|
||||
* @see DriverManager#deregisterDriver(Driver)
|
||||
* @since 1.8
|
||||
*/
|
||||
void deregister();
|
||||
|
||||
}
|
@ -110,6 +110,14 @@ public class DriverManager {
|
||||
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-----------------------------
|
||||
|
||||
/**
|
||||
@ -309,21 +317,42 @@ public class DriverManager {
|
||||
|
||||
|
||||
/**
|
||||
* Registers the given driver with the <code>DriverManager</code>.
|
||||
* Registers the given driver with the {@code DriverManager}.
|
||||
* A newly-loaded driver class should call
|
||||
* the method <code>registerDriver</code> to make itself
|
||||
* known to the <code>DriverManager</code>.
|
||||
* the method {@code registerDriver} to make itself
|
||||
* known to the {@code DriverManager}. If the driver had previously been
|
||||
* registered, no action is taken.
|
||||
*
|
||||
* @param driver the new JDBC Driver that is to be registered with the
|
||||
* <code>DriverManager</code>
|
||||
* {@code DriverManager}
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
public static synchronized void registerDriver(java.sql.Driver driver)
|
||||
throws SQLException {
|
||||
|
||||
registerDriver(driver, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given driver with the {@code DriverManager}.
|
||||
* A newly-loaded driver class should call
|
||||
* the method {@code registerDriver} to make itself
|
||||
* known to the {@code DriverManager}. If the driver had previously been
|
||||
* registered, no action is taken.
|
||||
*
|
||||
* @param driver the new JDBC Driver that is to be registered with the
|
||||
* {@code DriverManager}
|
||||
* @param da the {@code DriverAction} implementation to be used when
|
||||
* {@code DriverManager#deregisterDriver} is called
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
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));
|
||||
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
|
||||
} else {
|
||||
// This is for compatibility with the original DriverManager
|
||||
throw new NullPointerException();
|
||||
@ -334,11 +363,29 @@ public class DriverManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a driver from the <code>DriverManager</code>'s list.
|
||||
* Applets can only deregister drivers from their own classloaders.
|
||||
* Removes the specified driver from the {@code DriverManager}'s list of
|
||||
* registered drivers.
|
||||
* <p>
|
||||
* If a {@code null} value is specified for the driver to be removed, then no
|
||||
* action is taken.
|
||||
* <p>
|
||||
* If a security manager exists and its {@code checkPermission} denies
|
||||
* permission, then a {@code SecurityException} will be thrown.
|
||||
* <p>
|
||||
* If the specified driver is not found in the list of registered drivers,
|
||||
* then no action is taken. If the driver was found, it will be removed
|
||||
* from the list of registered drivers.
|
||||
* <p>
|
||||
* If a {@code DriverAction} instance was specified when the JDBC driver was
|
||||
* registered, its deregister method will be called
|
||||
* prior to the driver being removed from the list of registered drivers.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static synchronized void deregisterDriver(Driver driver)
|
||||
@ -347,11 +394,22 @@ public class DriverManager {
|
||||
return;
|
||||
}
|
||||
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
sec.checkPermission(DEREGISTER_DRIVER_PERMISSION);
|
||||
}
|
||||
|
||||
println("DriverManager.deregisterDriver: " + driver);
|
||||
|
||||
DriverInfo aDriver = new DriverInfo(driver);
|
||||
DriverInfo aDriver = new DriverInfo(driver, null);
|
||||
if(registeredDrivers.contains(aDriver)) {
|
||||
if (isDriverAllowed(driver, Reflection.getCallerClass())) {
|
||||
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.action() != null) {
|
||||
di.action().deregister();
|
||||
}
|
||||
registeredDrivers.remove(aDriver);
|
||||
} else {
|
||||
// If the caller does not have permission to load the driver then
|
||||
@ -639,8 +697,10 @@ public class DriverManager {
|
||||
class DriverInfo {
|
||||
|
||||
final Driver driver;
|
||||
DriverInfo(Driver driver) {
|
||||
DriverAction da;
|
||||
DriverInfo(Driver driver, DriverAction action) {
|
||||
this.driver = driver;
|
||||
da = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -658,4 +718,8 @@ class DriverInfo {
|
||||
public String toString() {
|
||||
return ("driver[className=" + driver + "]");
|
||||
}
|
||||
|
||||
DriverAction action() {
|
||||
return da;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,8 +30,9 @@ import java.security.*;
|
||||
|
||||
/**
|
||||
* The permission for which the <code>SecurityManager</code> will check
|
||||
* when code that is running in an applet, or an application with a
|
||||
* when code that is running an application with a
|
||||
* <code>SecurityManager</code> enabled, calls the
|
||||
* {@code DriverManager.deregisterDriver} method,
|
||||
* <code>DriverManager.setLogWriter</code> method,
|
||||
* <code>DriverManager.setLogStream</code> (deprecated) method,
|
||||
* {@code SyncFactory.setJNDIContext} method,
|
||||
@ -95,14 +96,16 @@ import java.security.*;
|
||||
* <code>Connection</code> or
|
||||
* objects created from the <code>Connection</code>
|
||||
* will wait for the database to reply to any one request.</td>
|
||||
* <tr>
|
||||
* <td>deregisterDriver</td>
|
||||
* <td>Allows the invocation of the {@code DriverManager}
|
||||
* method {@code deregisterDriver}</td>
|
||||
* <td>Permits an application to remove a JDBC driver from the list of
|
||||
* registered Drivers and release its resources.</td>
|
||||
* </tr>
|
||||
* </tr>
|
||||
* </table>
|
||||
*<p>
|
||||
* The person running an applet decides what permissions to allow
|
||||
* and will run the <code>Policy Tool</code> to create an
|
||||
* <code>SQLPermission</code> in a policy file. A programmer does
|
||||
* not use a constructor directly to create an instance of <code>SQLPermission</code>
|
||||
* but rather uses a tool.
|
||||
* @since 1.3
|
||||
* @see java.security.BasicPermission
|
||||
* @see java.security.Permission
|
||||
|
Loading…
x
Reference in New Issue
Block a user