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

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: 2010-01-31 02:08:50
Message-ID: hk2onk$djr$ (view raw or whole thread)
Lists: pgsql-jdbc
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.

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 

> 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
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 

> ...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 

> 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?


In response to

pgsql-jdbc by date

Next:From: Richard TroyDate: 2010-01-31 03:49:27
Subject: Re: driver initialization and connection separation
Previous:From: Oliver JowettDate: 2010-01-31 02:08:27
Subject: Re: driver initialization and connection separation

Privacy Policy | About PostgreSQL
Copyright © 1996-2015 The PostgreSQL Global Development Group