aspose file tools*
The moose likes JDBC and the fly likes Why use Class.forName() to load driver Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » JDBC
Bookmark "Why use Class.forName() to load driver" Watch "Why use Class.forName() to load driver" New topic
Author

Why use Class.forName() to load driver

Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
If we just create a reference of the driver(say: sun.jdbc.odbc.JdbcOdbcDriver) and say new,
the driver gets loaded...also since each driver has a
static block it will register itself with the DriverManager
All the code works fine.

Then why is Class.forName() used to load a driver???
anand correia
Greenhorn

Joined: Mar 09, 2006
Posts: 1
The class.forName() is used when we donot know the driver class name, therefore we just pass string name and load class in the memory.

for e.g. class.forName("name")

depending upon "name" it will dynamically load the class and return class provided the class ia available in class path.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
The class.forName() causes the ClassLoader to load the class into memory. JDBC driver classes contain a static initializer block that registers the driver with DriverManager for later reference. When you connect DriverManager uses the database parameter to look up the right driver. Here's a connection I use:

The "jdbc: db2:" part of the string matches a driver I loaded earlier.

This is pretty slick, but it's in the non-obvious category. It might have been better for Sun to define a more explicit way of registering drivers. Wait! They did:


Edited: There are no spaces in that "jdbc: db2" string but I put one in to avoid making smileys.
[ March 09, 2006: Message edited by: Stan James ]

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Jeanne Boyarsky
internet detective
Marshal

Joined: May 26, 2003
Posts: 30309
    
150

Originally posted by Stan James:
Edited: There are no spaces in that "jdbc: db2" string but I put one in to avoid making smileys.

Just want to make sure (and everyone else) know there is a checkbox to disable smilies in a post if you scroll down on the screen where you type in the message. Very useful when posting code!


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
Firslty Thanks for replying

@Anand: I agree that we can load the class with the help of the static
forName() method but the string that you pass to it should still be
Phonetically matching the actual class.So if this is the case then we
already have the class name....just call new on it...

@Stan: The Code:
Driver driver = (Driver) Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").
newInstance();
DriverManager.registerDriver(driver);
is more self-explainatory than:

Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");
Connection con=DriverManager.getConnection(/*URL*/);

That is exactly what I wanted to know...then why is that all the
documentations and tutorials on JDBC suggest the use of second method??
stu derby
Ranch Hand

Joined: Dec 15, 2005
Posts: 333



@Stan: The Code:
Driver driver = (Driver) Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").
newInstance();
DriverManager.registerDriver(driver);
is more self-explainatory than:



... and creates two instance of the driver and registers both of them (which is probably harmless). One instance is created and registerd by the code above and one is creating in the Driver's initialization block.

It's relatively harmless to do it Stan's way, unless for some weird reason the driver breaks if there are 2 instances of the class... that would be a poorly written driver, IMHO.
[ March 09, 2006: Message edited by: stu derby ]
Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
One instance is created and registerd by the code above and one is creating in the Driver's initialization block.


Sorry i didn't get you Stu...
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Interesting point, Stu. I copied that from somewhere the first week I tried JDBC and haven't looked at it since. (The power of reusable objects!)

Ashutosh, that makes two instances of the driver because the static initializer makes one instance the first time I reference the class for any reason, and the newInstance() call makes another.

Maybe DriverManager is smart enough to only keep a reference to one of those and the other goes to GC. It seems to work anyhow.
Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
Driver driver=new COM.ibm.db2.jdbc.app.DB2Driver();
DriverManager.registerDriver(driver);



Will this work??
Joel McNary
Bartender

Joined: Aug 20, 2001
Posts: 1817

@Anand: I agree that we can load the class with the help of the static
forName() method but the string that you pass to it should still be
Phonetically matching the actual class.So if this is the case then we
already have the class name....just call new on it...


You might not already have it. It could be read in from a configuration file (XML/properties file).

As far as the reason that they use static initializers, personally, I think that they just wanted to show off the cool static initializer capabilities of Java. But there could be a more sinister and obtuse reason (although I'm not sure theis fully explains the reason): A specific JDBC driver can only be used in a class that was loaded by the same class loader as the one that loaded the driver.

Hunh? What was that, again? Could you please repeat that?

OK. A specific JDBC driver can only be used in a class that was loaded by the same class loader as the one that loaded the driver. So if Class A was loaded by ClassLoader Z, and you ask for Driver.getConnection("..."), the JDBC driver that matches that URL had better also been loaded by ClassLoader Z -- otherwise you get a no valid driver exception.

So, since Class.forName turns around and calls the *system* classloader, you get the driver loaded in the standard classloader. This is fine, unless you are trying to reference a Driver loaded by a different class loader (or if you are in a class loaded by a non-system classloader).

Granted, calling new JDBCDriverClass() should do the same thing, but there may be differences internally that make the .forName() preferred over the .new(). That, and you don't actually have to create a new instance of the driver.

Now, why they chose to make this distinction based on ClassLoader, I'm not sure. Perhaps someone could try to explain that one.


Piscis Babelis est parvus, flavus, et hiridicus, et est probabiliter insolitissima raritas in toto mundo.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Ashutosh, your sample with new COM.ibm.db2.jdbc.app.DB2Driver() should work. The big difference between my post and that is that you have a compile time dependency on the IBM driver and I wanted to avoid it.

I have a handful of little connector classes for different databases. I move the code between work and home. Work uses one RDBMS and home uses another. Neither machine has all the drivers installed, yet none of the connector classes have any compile problems because the driver classnames are all in strings. Does that makes sense?

Here's a complete example of the concrete classes:

I copied this method of registering drivers from some example code before I knew about the static initializer method. This may well be sub-optimal, but it works just fine for my small scale personal projects.
[ March 11, 2006: Message edited by: Stan James ]
Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
That was amazing...!!!
Thanks Joel,Thanks Stan....You people had been a great help...
I think my problem is almost solved..
Savio Fernandes
Greenhorn

Joined: Apr 14, 2005
Posts: 16
I have a question which moves off a little from what's being discussed.

So, it is possible to have more than one driver, for the same database, registered at the same time with the DriverManager, right?

If the above is correct, then how does the DriverManager decide which driver to use, when I call the getConnection() method?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41524
    
  53
By looking at the URL of the connection - each driver handles a specific type of connection URL. If you have different drivers, they would have different URLs.


Ping & DNS - my free Android networking tools app
Ashutosh Limaye
Ranch Hand

Joined: Oct 24, 2005
Posts: 58
The DriverManager maintains a Table(may be a Map)for all the drivers that are registered.The URL that you pass to the getConnection() acts like the name in a name-value pair, the value is the desired driver.

Hmmm...I'm I making sense?!
Raghvendra Tiwari
Greenhorn

Joined: Jan 29, 2010
Posts: 1

Thanks to codereanch and it's all menber....
It really solved my problem....
Thanks Again
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why use Class.forName() to load driver