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

Re: context classloader

From: Oliver Jowett <oliver(at)opencloud(dot)com>
To: Vadim Nasardinov <vadimn(at)redhat(dot)com>
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: context classloader
Date: 2005-01-19 20:53:53
Message-ID: (view raw, whole thread or download thread mbox)
Lists: pgsql-jdbc
Vadim Nasardinov wrote:
> On Tuesday 18 January 2005 23:12, Oliver Jowett wrote:

>>It is even less predictable when the static initializer will be run
>>(and therefore what the CCL will be set to at that point). What's
>>the point?
> The same goes for getClass().getClassLoader().  It's not predictable
> what this returns.

Two comments:

Firstly, your statement is not true. getClass().getClassLoader() will 
always return the classloader that was used to load the driver class, 
which *is* predictable. You can always, for example, put in the path of the same classloader that loads 
the driver (at worst, by packaging it directly in the driver jar) and 
the driver will find it. In contrast, if you're relying on the CCL, you 
have essentially no guarantees about where it will search. It could be a 
completely unrelated CL that can't even see the driver jar!

Secondly, I think you missed my point. It is the *timing* of 
initialization that I am concerned about. Timing of class initialization 
is hard to predict; how do you make sure that the CCL is correctly set 
when this happens? How do you document this so that users don't get 
confused? It seems unreasonable to require someone who just wants to use 
the JDBC driver to have to understand the mechanics of class 
initialization and guard against accidentally causing initialization 
before they're ready!

>>What is special about [...] the first action that happens to cause
>>class initialization (if you go with magic in the static
> It's special because it determines the result of
> getClass().getClassLoader().

It does not. getClass().getClassLoader() always returns the classloader 
that loaded org.postgresql.Driver, regardless of the environment when 
class initialization is triggered. The returned classloader will not 
change during the lifetime of a particular copy of the Driver class.

If you are using the CCL to locate the defaults, then either the context 
set during initialization is somehow special (if you only load the 
defaults once) or you must load the defaults on every getConnection() 
and they can change depending on the caller's context. I don't like 
either behaviour.

> For the sake of completeness, what do you think of doing nothing in
> the case when the driver is loaded by the bootstrap classloader?  In
> other words, wrap the affected chunk of code in the following
> conditional:
>         if (getClass().getClassLoader() != null) {
>             // load the /org/postgresql/ files
>         }

It could do that (it does that if the system classloader is null) but it 
seems less useful -- why can the driver suddenly no longer load defaults 
if it ends up in the bootstrap classpath?

Ideally we need some way to get resources directly from the bootstrap 
classloader, but ClassLoader does not give us a way to do that. Using 
the system classloader seems like the best approximation.

>>Yes. getClass() tends to be a bit friendlier to anything that tweaks
>>the bytecode, though, since a .class reference compiles down to a
>>call to Class.forName() which breaks if the class is renamed, etc.
> Out of curiosity, is it a formal policy of the pgsql-jdbc project to
> be friendly to bytecode mungers?  What other guidelines does one need
> to be mindful of?

Personally I write lots of other code that has to be friendly to 
bytecode mungers, so it becomes force of habit. It's not a formal 
policy, just one of my own code hygiene rules.


In response to


pgsql-jdbc by date

Next:From: Avramucz IstvánDate: 2005-01-20 10:17:30
Subject: DataSource
Previous:From: Amit_WadhwaDate: 2005-01-19 15:17:37
Subject: unsubscribe

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