DriverManager.isDriverAllowed has an unintentional side-effect?

Lance Andersen lance.andersen at
Mon Feb 10 20:35:11 UTC 2020

Hi Jaikiran

> On Feb 10, 2020, at 10:09 AM, Jaikiran Pai <jai.forums2013 at> wrote:
> Right now within the implementation of APIs in java.sql.DriverManager
> there are classloader checks to ensure whether the caller is allowed
> access to registered drivers. For example the getDriver(String url)
> API[1] calls the isDriverAllowed (private) method[2] to check if the
> registered driver is allowed access from the caller's classloader. The
> implementation of isDriverAllowed has this[3]:
> aClass =  Class.forName(driver.getClass().getName(), true, classLoader);

This dates back to JDK 1.2 (1998/99) and I would be hesitant to change this at this time
> Is it intentional to intialize that class by passing "true" to the
> forName call? The reason I ask is the following scenario:
> 1. Imagine a multi classloader environment.
> 2. Consider postgres JDBC driver (from postgres.jar) gets loaded through
> classloader C1 and is registered in DriverManager in context of C1.
> 3. Now consider a class A loaded in classloader C2. Let's say this C2
> also has postgres.jar in its classpath but hasn't yet loaded any of the
> classes from it yet nor have any calls to "registerDriver" been made by
> any of the classes loaded by this C2.
> 4. Class A (in context of C2) now calls getDriver(String url) passing it
> a JDBC url corresponding to postgres. This will result in a
> SQLException("No suitable driver") exception and that's fine, because C2
> isn't allowed access to driver registered in context of C1. However, now
> consider the following code(again within class A in context of C2):
> try {
>     DriverManager.getDriver("jdbc:postgres:....");
> } catch (SQLException e) {
>   // expected
>   // now lets do the same call again
>   driver = DriverManager.getDriver("jdbc:postgres:...."); --> this one
> passes
> }
> So what's being done is, the SQLException("no suitable driver") is
> caught and the exact same call which triggered this issue, is called
> again. This time the call passes and returns a JDBC driver corresponding
> to the postgres driver.
> Looking at the implementation of DriverManager (which I linked before),
> I can understand why this happens but it just seems odd that the API
> would behave in this manner (that too with no indication in the
> documentation).
> What really is happening here is that the current implementation of
> isDriverAllowed, due to its usage of "true" to initialize the driver
> class ends up triggering the Driver's static block (which as per the
> JDBC spec) is expected/mandated to register with the DriverManager. As a
> result, this call ends up registering the driver, now in the context of
> C2 and as a result the subsequent calls to this (and other APIs) start
> passing from classes loaded by C2 (like that class A).
> Should this check in the isDriverAllowed, instead use "false" and not
> trigger the intialization of the class?

As I mentioned above, this dates back to the very early days of JDBC and JDK 1.2.  Any changes in this area could be quite disruptive and would require extensive testing. 

> [1]
> [2]
> [3]
> -Jaikiran


 <> <>
 <>Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037
Oracle Java Engineering 
1 Network Drive 
Burlington, MA 01803
Lance.Andersen at <mailto:Lance.Andersen at>

More information about the core-libs-dev mailing list