Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search archives
  Advanced Search

Re: driver initialization and connection separation


  • From: Lew <noone(at)lwsc(dot)ehost-services(dot)com>
  • To: pgsql-jdbc(at)postgresql(dot)org
  • Subject: Re: driver initialization and connection separation
  • Date: Sat, 30 Jan 2010 21:08:50 -0500
  • Message-id: <hk2onk$djr$1@news.albasani.net> <text/plain>

Richard Troy wrote:
The application can connect to any RDBMS, Postgres, Oracle, Ingres,
whatever, and reconnect to any other, whenever the user wants. But once it
has connected to Postgres using the SSL feature, all future connections
using Postgres will use SSL. The only solution thus far is to kill the
application and then start it again - there is no switching between using
SSL and not using SSL, even though the driver is officially reloaded using
Class.forName(driverClassName).

As Oliver pointed out, that does not reload the driver.

Note that the official Java documentation from Sun says that doing so is
equivalent to Class.forName(className, true, currentLoader) which is using
the method for.Name(name, initialize, ClassLoader) - I cited a URL to
their site to support this.

Once a class loader has loaded the class, it does not reload it again but determines that it already has done so.

To me this says that subsequent executions of Class.forName("driver")
should yield identical results as with the first time it's executed, but

To you, maybe, but not in reality. Your perception will match reality once you've read the documentation.
<http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html>

If you use a different class loader you can load the class again, but that poses other gotchas.

that's demonstrably not true with Postgres - it "remembers" that it was
asked to use SSL in the past and it continues to want to do so in the
future.

Remembering that it used SSL is not curable by failing to reload the class.

It seems to me that there's something missing from the initialization
code, namely to remove the SSL features if the driver was already loaded.

The class is not re-initialized since you're using the same class loader and it was already initialized once. Ergo, nothing is missing from the initialization.

It should only be loaded when a URL asking for it comes along with the
option ssl=true (for example). However, one could easily argue that it's
not the initialization code that needs help but the code that constructs a
new connection; it makes just as much sense that the request for a new
connection give the appropriate type of connection, with or without SSL
depending on whether the option in the URL was specified.

According to how I read
<http://jdbc.postgresql.org/documentation/84/connect.html>
you should be able to get a non-SSL connection by not specifying the "ssl" property in the version of 'DriverManager.getConnection()' that takes a 'Properties' argument.

...I readily admit I haven't tried making multiple, simultaneous
connections from the same instance of the driver; I presume that's
possible but I've never needed. It seems to me this is
much more a question of each individual connection than the driver itself.

You use the driver with static methods, such as 'DriverManager.getConnection()'. AFAICS there is no access directly to driver instances.

...Your follow-on comment (below) about classes being initialized only
once isn't helpful here because it isn't clear to me whether this is a
case of initializing an object or loading _code_ that instantiates

He wasn't talking about initializing objects. He was talking about initialization of the driver *class*, and it's entirely relevant. Whether it's helpful to you or not depends on whether you assimilate and act upon the information.

objects. In other words, even though I've been using Java since it's first
release, I've never before had to worry about the code that instantiates
objects changing while my code is running, so I haven't thought about it

Again, this is not about instantiation.  You really should think about it much.

much. To my mind, each instance of my objects which then instantiate other
objects - like JDBC connection objects - should get clean, separate and
distinct objects, so in effect the driver code is loaded multiple times.

Not how it works.  Your mind needs to change on this.

But as I said, I could be wrong - I don't know much about how the JVM
manages code that's loaded, but my suspicion is that it'll manage the
individual instances of loading the same driver separately.

Nope.  It's not about instances.

Meanwhile, I just added this bit of code prior to the call to
Class.forName():

  for (Enumeration fu = DriverManager.getDrivers(); fu.hasMoreElements();)
  {
     DriverManager.deregisterDriver((java.sql.Driver)fu.nextElement());
  }

As I said, I don't have to worry about multiple connections within a
single instance of this class, so deregistering all the drivers is fine -

I am not so sure about that. It seems like an awful lot of work, and how will it reregister? Once loaded and initialized, a class will not reinitialize unless it's actually garbage collected first. Since registration is part of intialization, and you don't get to reinitialize, I don't think you'll get the class to re-register. Deregistration is not idiomatic and I expect it will cause heartache. Better go with a conventional approach.

there should only ever be one connection and we're about to replace it. If
there's an unacceptable performance hit for unloading a driver when it

Deregistration != unloading.

isn't needed, then I'll think about adding to this. But if it works, it's
staying! -smile- I'll probably test it in the next few minutes...

Better would be to use the correct approach, which might be the 'DriverManager.getConnection()' call to which I just alluded. I haven't tested it yet - why don't you and let us know how it works?

--
Lew



Home | Main Index | Thread Index

Privacy Policy | About PostgreSQL
Copyright © 1996 – 2012 PostgreSQL Global Development Group