Java Class.forName(String className) and JDBC

A reader asked a question via a comment a couple months ago that I didn’t really have an answer for (and had always kind of wondered the same thing). In the original post (which showed how to use JDBC with ColdFusion), I used the following snippet of code:

Class.forName("jdbc.DriverXYZ");
Connection con = DriverManager.getConnection(url,
  "myLogin", "myPassword");

and the reader wanted to know what the Class.forName(..) method did. The most common answer you’ll hear is that it loads the database driver, which, while technically true, is shallow. Where does it get loaded? How does it happen? And why?

To answer the question I started with the JavaDoc for the Class.forName() method. According to the documentation, the method:

… attempts to locate, load, and link the class or interface

I wasn’t perfectly clear on what “locate, load, and link” meant, so I did a little digging through the Java Language Specification. According to chapter 12 of the JLS:

Loading refers to the process of finding the binary form of a class or interface type with a particular name, perhaps by computing it on the fly, but more typically by retrieving a binary representation previously computed from source code by a compiler, and constructing, from that binary form, a Class object to represent the class or interface.

Next, again according to the JLS, it must be transformed from it’s binary representation to something the Java virtual machine can use, this process is called linking. Finally, the class is initialized, which is the process that executes the static initializer and the initializers for static fields declared in the class.

So then back to the original problem, when Class.forName() is called with an argument like this:

Class.forName("org.gjt.mm.mysql.Driver");

the classloader attempts to load and link the Driver class in the “org.gjt.mm.mysql” package and if successful, the static initializer is run. The MySQL Driver (download the source code) static initializer looks like this:

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

So it calls a static method in the java.sql.DriverManager class which apparently registers a copy of itself when it loads.

So now I understand the where and the how, what about why? To understand the why you have to look at the next line in the initial code example:

Connection con = DriverManager.getConnection(url,
  "myLogin", "myPassword");

The DriverManager class (view DriverManager source here) returns a database connection given a JDBC URL string, a username and a password. In order to create that connection, the DriverManager class has to know which database driver you want to use. It does that by iterating over the array (internally a Vector) of drivers that have registered with it (ie: the registerDriver(Driver driver) method illustrated above) and calls the acceptsURL(url)) method on each driver in the array, effectively asking the driver to tell it whether or not it can handle the JDBC URL.

So there you have it. Class.forName explained.

This entry was posted in ColdFusion, J2EE, Software Development. Bookmark the permalink.

54 Responses to Java Class.forName(String className) and JDBC

  1. meh says:

    “Class.forName explained.” More like: Hidden-magic antipattern exposed! Or: Thank god for open-source where you can see what’s actually happening under-the-covers.

  2. alma says:

    >Thank god for open-source where you can see what’s actually happening under-the-covers.

    A good specification should do it ;-)

  3. Gopi says:

    Good one !!

  4. Murthy says:

    why can’t the following code do the job of “locate, load, and link”?

    org.gjt.mm.mysql.Driver driver = new org.gjt.mm.mysql.Driver();

    This would locate , load and link by executing the static block

    Thanks,

  5. Anooj says:

    Can you please mention how the entry is being made in the DriverManager only when a driver is loaded using Class.forName() instead of a class like java.util.Vector ?What will happen if a class like vector is loaded using Class.forName() ?

  6. Kiran says:

    Good one Thank you

  7. maitri says:

    simple and good

  8. Kirtish Parekh says:

    Never found such explained answer on the forums. I think its our duty as a java developer to work on the common problems like this.

    Thanks for the details.

  9. Chaitanya says:

    Great Aaron…..good explanation…..you are really great..!!

  10. Janeve George says:

    This are some hidden facts that most of the Java Masters might be unaware of. Thanks for sharing this information.

  11. vivek says:

    It is really very good
    thank you.

  12. zajjar says:

    Thank you very much for this explanation! Now it’s clear for me :)

  13. Seb says:

    Very good explanation… I had encountered that piece of code a lot of times but never understood what was going on under the covers.
    A search on google returned your website and that was an interesting read!

  14. vedang says:

    nice… thanks for clearing the concepts…

  15. Moe says:

    Crystal! Good Job!

  16. snehal says:

    Please tell me if we write to class.forName() statements simultaneously trying to load diferent drivers.ir first i load oracle driver and then jdbc which one will it load

  17. amirthan says:

    Neatly explained.Thanks

  18. poonam says:

    we dont have DriverManger class in j2me then how to etablish connection

  19. M.Shylaja says:

    Thanks for ur Information. Cleared my doubt.

  20. Sree Ram says:

    Thanks a real lot. People often do this stufff without understanding why and the explanation was crystal clear.

  21. Mete Takil says:

    Thanks a lot. Now I know why Class.forName(aString) is used.

  22. raghu says:

    excellent work…..thanks to the author

  23. encoded says:

    Nice job! i was googling and googling and found this, after reading through the spec and going through the class Class, makes perfect sense, thanks for making me lazy, hehe!

  24. Vasan says:

    Well written and to the point! Now I understand!
    On the why part – why does the standard way of opening a database be so complex? i.e. Loading the driver in step 1, and passing a URL in the step 2 which (hopefully) identifies the driver in step 1. Why not simply call the DriverManager with both the driver class, and the URL in one call? (The driver manager can do step 1 and 2 internally?).

  25. cvasilak says:

    Thanks for explaining the magic! :)

  26. dONI jAMES says:

    Thanks, You r coool

  27. hrishikesh says:

    such a outstanding approach. honestly , it is the best on the web.

  28. Rajesh says:

    Hatsoff 2 the author.your explanation is a lesson for all of us not only belonging to this subject, But we can follow your way while posting further explanation on the web.

  29. Ram Dixit says:

    Great Explaination of Class.forName(),
    Before this page I had gone through lot of websites but didn’t get the explaination as in this page.

    Thanks a lot Mr. Aaron Johnson.

  30. swapnil says:

    Nice Article ………..

  31. Jujahar says:

    Just Great…. Thanks..

  32. Lasith says:

    Thanx a lot Aron.

  33. Girish Limaye says:

    Understood how internally database connection works.
    Really cooool!!
    Thank a lot.

  34. Abhinav says:

    Its really nice……………..thanks.

  35. JP says:

    Thank you for the explanation!

  36. Surendra says:

    Good explaination..:)

  37. Viswanath says:

    Really gives a deep insight…
    Thanks you very much

  38. Mabura says:

    Hey, aren’t u great !!

  39. Dhanusha Dhanendran says:

    Thanx Aaron… Now really understood how connwctivity code works… thanks a lot…

  40. deep says:

    I am getting Class not Found Exception when i pass parameter to the class
    String abc = “ABC”;
    String xyz = “XYZ”;
    String str = “com.app.ProductDet(“+abc+”,”+xyz+”)”;
    Class c = Class.forName(str);
    try{
    AClass ac = (AClass) c.newInstance();
    }catch(AllException e)

  41. Harsh says:

    Thanks Aaron. You save me a lot of research time :)

  42. john says:

    nice work………

  43. vinay says:

    very nice …… tanq for the info………

  44. Ravidnra says:

    Yeah man it’s very nice
    we can know lot from this

  45. divya says:

    I understood the concept but when we use new operator for the Driver, Why we need to register again. Does not new operator execute the static block and register the driver.

  46. Chris says:

    Thanks a lot, that really helps explain it. Quite clever really.

  47. BP says:

    To whom class.forname(…) method returns the value?

  48. hellfire7707 says:

    Awesome explanation.

    It really works out for me.

    Thank you~!!

  49. Vishal says:

    Hello,
    Its a good for all java developer.
    And i hope you will post new magic soon.
    Thanx

  50. manigandan.p says:

    good one

  51. Kunal says:

    Nice job johnson.
    Thanks for sharing this……

  52. Pattanaik says:

    Hi ,Thanks for the insight.
    Something now comes to my mind like can I create my connection object avilable by below..?

    Driver driver = new RespectiveDriverClassVendor();
    Connection con =DriverManager.getConnection();

    Though staticblock is in Driver Implemetation class is taking care of binding it to Drivermanager class.

  53. Amit says:

    Awesome!

  54. Nagu says:

    Plz tell in simple words

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>