How JDBC URLs get mapped to connections at runtime

Who cares?

I recently found the need to mock out a JDBC url to experiment with a new way of testing sqoop without a hard dependency on a particular database installation.  In order to do this, you first need to understand how it is that, at runtime, JDBC drivers connection call URLs get routed to implementation specific drivers.


How do JDBC URL’s get converted to implementation specific class implementations of the java.sql.Driver interface?

We’ve all used the canonical JDBC connect snippet for connecting to relational databases from the JVM.

Connection conn = null;
Statement stmt = null;
try{
      Class.forName("com.<database_vendor>.jdbc.Driver");
      conn = DriverManager.getConnection(DB_URL,USER,PASS);
      stmt = conn.createStatement();
      ... 
}
  

What is this code actually doing?

A quick look at the DriverManager class reveals that when we call “getConnection”, a data structure is scanned for available drivers which parses out the connection URL:

SQLException reason = null;
for (int i = 0; i < drivers.size(); i++) {
   DriverInfo di = (DriverInfo)drivers.elementAt(i);
   ... 
   if (di.driver.acceptsURL(url)) {
                    // Success!
                    println("getDriver returning " + di);
                    return (di.driver);
   }
}

So… how do the “drivers” get populated ?    

It turns out that the magic  call to:

Class.forName("com.mysql.jdbc.Driver")

Actually induces a static initialization block (any time a class is loaded, any static code in it gets executed).  So, the JDBC Driver implementations have an soft requirement associated with them which is that they call:

java.sql.DriverManager.registerDriver(new ClientDriverImplementation())

Where the implementation actually implements the “acceptsURL” method.  The below is an excerpt from the derby JDBC driver (similar blocks exist in com.mysql.jdbc.Driver, etc…)

static {
...
  registeredDriver__ = new ClientDriver();
  java.sql.DriverManager.registerDriver(registeredDriver__);
...
}

Thanks to the wonderful folks at stack overflow for helping to clarify the static initializer part.   http://stackoverflow.com/questions/5484227/jdbc-class-forname-vs-drivermanager-registerdriver.

In summary

So.. anyways… the moral of the story is that there is nothing magic about the database connection urls.  You could make your own database connection url as a mock connection with any kind of url text in it, as long as the class.forName(…) method was called in the beggining of your database connection workload, the java.sql.Driver class will be able to figure out what implementation class to map the connection URL to.

 

FROM HERE

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s