Alex Erohin Alex Erohin - 3 months ago 18
Java Question

JDBC Driver implementation and class loading

Not a long time ago I was implementing JDBC driver. But before jumping into work I've studied some MySQL JDBC driver sources and found out that they contain two implementations of the

java.sql.Driver
interface: com.mysql.jdbc.Driver and com.mysql.jdbc.NonRegisteringDriver, where
Driver
also extends
NonRegisteringDriver
.

The
Driver
class only contains a static block that calls
DriverManager.registerDriver()
to register the class:

static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}


While
NonRegisteringDriver
implements all the
java.sql.Driver
interface methods.

My first thought was, that by implementing a driver this way developers of MySQL driver are following java.sql.Driver guidlines that state the following:


It is strongly recommended that each Driver class should be small and standalone so that the Driver class can be loaded and queried without bringing in vast quantities of supporting code.


But if I understand Java classloading correctly, there is absolutely no point in having separate
com.mysql.jdbc.Driver
class, as its parent with all the realisation code will be loaded anyway before execution of the static block.

Am I missing something here?

Answer

No, actually without com.mysql.jdbc.Driver class present implementation of mysql JDBC driver will not satisfy java.sql.Driver agreement, which claims:

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

Class.forName("foo.bah.Driver")}  

com.mysql.jdbc.NonRegisteringDriver class doesn't contain this part of creating self-instance and registering it.

Why did mysql developers decided to distinguish implementation itself from class which essentially registers its instance? Hard to say exactly, but it could be convenient in case if they will decide to provide several implementations in same package. Then class com.mysql.jdbc.Driver will extend default one.

UPDATE: Essenstially things are as I described above. There are at least 3 derived classes which extend com.mysql.jdbc.NonRegisteringDriver:

  • com.mysql.jdbc.Driver
  • com.mysql.fabric.jdbc.FabricMySQLDriver
  • com.mysql.jdbc.NonRegisteringReplicationDriver

While com.mysql.jdbc.Driver is default implementation, others overrides some methods from base class. If NonRegisteringDriver would contain static block for creation its instance and registering it, it would be not possible to have exactly one needed mysql driver in memory with deriving classes.

But in general there is no strong reasons for that. For example org.postgresql.Driver implementation contains full implementation of java.sql.Driver in itself.