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$1@news.albasani.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
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.
<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

In response to

Browse pgsql-jdbc by date

  From Date Subject
Next Message Richard Troy 2010-01-31 03:49:27 Re: driver initialization and connection separation
Previous Message Oliver Jowett 2010-01-31 02:08:27 Re: driver initialization and connection separation