Re: context classloader - Mailing list pgsql-jdbc
From | Oliver Jowett |
---|---|
Subject | Re: context classloader |
Date | |
Msg-id | 41EEC8E1.1010007@opencloud.com Whole thread Raw |
In response to | Re: context classloader (Vadim Nasardinov <vadimn@redhat.com>) |
Responses |
Re: context classloader
|
List | 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 driverconfig.properties 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 >>initializer)? > > 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/driverconfig.properties 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. -O
pgsql-jdbc by date: