Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Idiom for forcing class loading?

1 view
Skip to first unread message

Tom Anderson

unread,
Nov 18, 2009, 1:12:56 PM11/18/09
to
Hi chaps,

We have a class which does some setup in a static block that needs to
happen early in the lifecycle of the app (this is a dubious design, but
there you go - it's largely forced on us from without). Thus, it needs to
get loaded early. We have an initialiser class which runs at a suitable
time, so that's where we'll load the class. What's the best way to do
this?

Before i came to it, the code looked like:

void initialise() {
Class.forName("com.example.Foo");
}

I didn't like that, because it's using a string constant where it could be
using something strongly typed, and so not getting enabling refactoring
and inspection in the IDE. I had a bit of a debate with my pair, and we
changed it to:

void initialise() {
Class.forName(Foo.class.getName());
}

Which works, solves the problem, and is clearly bonkers.

What's a good idiom? One option would be to call a no-op method on the
class literal:

void initialise() {
Foo.class.getName();
}

But that's a bit hackish too. I could just store it in a local:

void initialise() {
Class foo = Foo.class;
}

Since i actually have several classes, i could put them in an array:

void initialise() {
Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
}

Am i right in thinking that all of these will force loading of Foo? Does
anyone have any other idioms? How about any opinions on which idiom is
best, or at least most idiomatic?

Thanks,
tom

--
A hypothesis or theory is clear, decisive, and positive, but it is
believed by no one but the man who created it. Experimental findings,
on the other hand, are messy, inexact things, which are believed by
everyone except the man who did that work. -- Harlow Shapley

markspace

unread,
Nov 18, 2009, 1:32:41 PM11/18/09
to
Tom Anderson wrote:

> void initialise() {
> Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
> }
>
> Am i right in thinking that all of these will force loading of Foo?

Well, rule #1 is "if it ain't broke don't fix it", so this whole
enterprise is dubious to me.

However, I don't see why these classes won't be loaded in any of the
examples you presented. The only issue I see is that an optimizer may
decide that the objects are "not used" and optimize them away. That is,
actually remove the statements referencing the classes.

Thus you might want to actually do something with the classes:

void initialise() {
Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};

Logger logger = Logger.getLogger( "x" );
for( Class c : loadedClasses ) {
logger.config( "Loaded class: "+c.getName() );
}
}

Replace "x" with the class name in which initialise() is declared.

This may also be bonkers, but it's a safe kind of bonkers, I think.

Peter Duniho

unread,
Nov 18, 2009, 1:36:12 PM11/18/09
to
Tom Anderson wrote:
> [...]

> Am i right in thinking that all of these will force loading of Foo?

I think so. But I haven't checked the spec to make sure.

> Does
> anyone have any other idioms? How about any opinions on which idiom is
> best, or at least most idiomatic?

I find the question ironic. :) The fact is, you've got some clearly
non-idiomatic scenario, where for some reason your code has managed to
become dependent on the initialization of a class that it does not in
fact refer to in the process of being dependent on it.

Given that violation of a very fundamental assumption one normally could
make in a Java program, asking for an idiomatic solution to the
violation seems sort of silly to me. Your code is already broken; any
work-around is destined to be non-idiomatic. :)

Pete

Tom Anderson

unread,
Nov 18, 2009, 2:01:01 PM11/18/09
to
On Wed, 18 Nov 2009, markspace wrote:

> Tom Anderson wrote:
>
>> void initialise() {
>> Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
>> }
>>
>> Am i right in thinking that all of these will force loading of Foo?
>
> Well, rule #1 is "if it ain't broke don't fix it", so this whole
> enterprise is dubious to me.

Son, you may wish to look into getting a new rule provider. If it ain't
broke but it's smelly, it's going to break, so fix it now before it does.

> However, I don't see why these classes won't be loaded in any of the
> examples you presented. The only issue I see is that an optimizer may
> decide that the objects are "not used" and optimize them away. That is,
> actually remove the statements referencing the classes.

Since class loading is side-effectual, i don't think an optimiser is free
to do that. Although i admit i'm a bit shaky about the rules on this.

> Thus you might want to actually do something with the classes:
>
> void initialise() {
> Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
>
> Logger logger = Logger.getLogger( "x" );
> for( Class c : loadedClasses ) {
> logger.config( "Loaded class: "+c.getName() );
> }
> }
>
> Replace "x" with the class name in which initialise() is declared.
>
> This may also be bonkers, but it's a safe kind of bonkers, I think.

It at least makes it look like something useful is being done, which is
what matters!

I also considered:

void initialise() {
loadClass(Foo.class);
}

void loadClass(Class cl) {
// do nothing!
}

!

Tom Anderson

unread,
Nov 18, 2009, 2:06:42 PM11/18/09
to

What's really happening is more like this:

class FooMangler implements Mangler {
static {
ManglerRegistry.register("foo", FooMangler.class);
}
}

class ManglingParser extends org.xml.sax.helpers.DefaultHandler {
public void startElement (String uri, String localName, String qName, Attributes attrs) throws SAXException {
String manglerName = attrs.getValue("mangler");
Mangler mangler = ManglerRegistry.lookup(manglerName);
mangler.mangle(qName, attrs);
}
}

The idea is that manglers can take care of registering themselves - as
long as they're loaded. This is an old and fairly well-known pattern (at
least, not wildly obscure - in terms of birds, about as common as a
kingfisher is in England), although i certainly wouldn't say it's a good
one, or even a non-dubious one. 'Broken' is a bit too strong, although
only a bit.

tom

--
Osteoclasts = monsters from the DEEP -- Andrew

Lew

unread,
Nov 18, 2009, 2:26:30 PM11/18/09
to
Tom Anderson wrote:
> We have a class which does some setup in a static block that needs to
> happen early in the lifecycle of the app (this is a dubious design, but
> there you go - it's largely forced on us from without). Thus, it needs to
> get loaded early. We have an initialiser class which runs at a suitable
> time, so that's where we'll load the class. What's the best way to do
> this?
...

> I could just store it in a local:
>
> void initialise() {
>         Class foo = Foo.class;
> }
>
> Since i [sic] actually have several classes, i [sic] could put them in an array:

>
> void initialise() {
>         Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
>
> }
>
> Am i [sic] right in thinking that all of these will force loading of Foo?
>

Yes, but not initialization. If all you need is loading, you're fine,
but if you need initialization, you're not..

Mere reference to the 'class' literal is forbidden to initialize the
class. JLS 12.4.1
<http://java.sun.com/docs/books/jls/third_edition/html/
execution.html#12.4.1>

This restriction is enforced in Sun JVMs starting with Java 5.

'Class.forName( String )' is documented to cause initialization but
'Class#getName()' is not so documented.
<http://java.sun.com/javase/6/docs/api/java/lang/Class.html#forName
(java.lang.String)>
<http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getName()>

It may be, however, that the latter is one of the "certain reflective
methods in class Class" to which the JLS refers, but without explicit
documentation of such it's a fragile promise/premise.

--
Lew

Thomas Pornin

unread,
Nov 18, 2009, 2:30:38 PM11/18/09
to
According to Tom Anderson <tw...@urchin.earth.li>:

> But that's a bit hackish too. I could just store it in a local:
>
> void initialise() {
> Class foo = Foo.class;
> }
>
> Since i actually have several classes, i could put them in an array:
>
> void initialise() {
> Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
> }
>
> Am i right in thinking that all of these will force loading of Foo?

You are right in that the class Foo will be _loaded_, but that is not
what you want. You want the class to be loaded _and_ initialized, and
here the Foo class is not initialized.

Class initialization occurs upon first "access": read or write to a
static field (not counting the pre-initialized final fields of a
'primitive enough' type to be inlined in the caller), call to a static
method, or creation of an instance. Note that creating an array of Foo
is not sufficient to get the Foo class initialized.

The standard JDK does not feature any direct method for initializing a
class; the least indirect one is Class.forName() (there are two
versions, one of which accepts a boolean which lets you find a class by
name without initializing it, the exact opposite of what you are looking
for).


--Thomas Pornin

Thomas Pornin

unread,
Nov 18, 2009, 2:34:44 PM11/18/09
to
According to Lew <l...@lewscanon.com>:

> <http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getName()>
>
> It may be, however, that the latter is one of the "certain reflective
> methods in class Class" to which the JLS refers, but without explicit
> documentation of such it's a fragile promise/premise.

Actually, calling Class.getName() on Sun's JDK 6 is not sufficient to
get the class initialized (try it !).


--Thomas Pornin

Alessio Stalla

unread,
Nov 18, 2009, 3:56:36 PM11/18/09
to

If you have control on the source code of the mangler, I would do like
this:

class FooMangler implements Mangler {
public static void autoregister() {}
...
}

and to initialize it, FooMangler.autoregister();

else, Class.forName(FooMangler.class.getName()) is the safest bet: it
always initializes the class and fails at compile time if FooMangler
is ever renamed (provided that the file containing the Class.forName
is recompiled!).

Alessio

Mike Schilling

unread,
Nov 18, 2009, 5:50:47 PM11/18/09
to
Tom Anderson wrote:
> Hi chaps,
>
> We have a class which does some setup in a static block that needs
> to
> happen early in the lifecycle of the app (this is a dubious design,
> but there you go - it's largely forced on us from without). Thus, it
> needs to get loaded early. We have an initialiser class which runs
> at
> a suitable time, so that's where we'll load the class. What's the
> best way to do this?

Add a static method to the class, called e.g. initialize(), and call
it.


Arne Vajhøj

unread,
Nov 18, 2009, 7:17:19 PM11/18/09
to

I don't think the problem is common enough to make a solution idiomatic.

I would without thinking twice:
- read class names from config file
- use Class.forName to initialize them

Arne

Kevin McMurtrie

unread,
Nov 19, 2009, 2:05:49 AM11/19/09
to
In article <alpine.DEB.1.10.0...@urchin.earth.li>,
Tom Anderson <tw...@urchin.earth.li> wrote:

You can access a non-optimizable static field or static method. A
constructor for an instance of the class is the safest bet.

Self-registering classes are not the best design. Under extremely rare
circumstances, references from live classes to the registration
container might not exist during a GC - then it's suddenly empty. In a
web server or other application with multiple ClassLoaders, it might not
be clear where things are going. For the work I've done, there were
enough problems to justify not using JDBC driver self-registration with
DriverManager.

Consider a configuration parameter that is a list of classes that your
registration container should load when it initializes.
--
I won't see Goolge Groups replies because I must filter them as spam

Roedy Green

unread,
Nov 19, 2009, 1:10:19 PM11/19/09
to
How about a dummy loadEarly/init static method that does nothing or
triggers static init code.
--
Roedy Green Canadian Mind Products
http://mindprod.com
Finding a bug is a sign you were asleep a the switch when coding. Stop debugging, and go back over your code line by line.

Jim Janney

unread,
Nov 19, 2009, 1:40:29 PM11/19/09
to
Tom Anderson <tw...@urchin.earth.li> writes:

To me what smells here is that ManglerRegistry is using static
methods. I'd prefer creating an instance of ManglerRegistry,
registering the appropriate manglers with it, and keeping a reference
to it in the ManglingParser. This requires more coding, obviously,
but gives you more flexibility in that different parsers can use
different registries. Also, it allows registering the same mangler
more than once under different names, which can sometimes be useful.

--
Jim Janney

Tom Anderson

unread,
Nov 19, 2009, 4:00:58 PM11/19/09
to
On Wed, 18 Nov 2009, Lew wrote:

> Tom Anderson wrote:
>> We have a class which does some setup in a static block that needs to
>> happen early in the lifecycle of the app (this is a dubious design, but
>> there you go - it's largely forced on us from without). Thus, it needs to
>> get loaded early. We have an initialiser class which runs at a suitable
>> time, so that's where we'll load the class. What's the best way to do
>> this?
> ...
>> I could just store it in a local:
>>
>> void initialise() {
>> � � � � Class foo = Foo.class;
>> }
>>
>> Since i [sic] actually have several classes, i [sic] could put them in an array:
>>
>> void initialise() {
>> � � � � Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class};
>>
>> }
>>
>> Am i [sic] right in thinking that all of these will force loading of Foo?
>
> Yes, but not initialization. If all you need is loading, you're fine,
> but if you need initialization, you're not..
>
> Mere reference to the 'class' literal is forbidden to initialize the
> class. JLS 12.4.1
> <http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4.1>

Aha! I had no idea this was the case! Thanks, and thanks to everyone else
who pointed it out.

> This restriction is enforced in Sun JVMs starting with Java 5.
>
> 'Class.forName( String )' is documented to cause initialization but
> 'Class#getName()' is not so documented.
> <http://java.sun.com/javase/6/docs/api/java/lang/Class.html#forName
> (java.lang.String)>
> <http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getName()>
>
> It may be, however, that the latter is one of the "certain reflective
> methods in class Class" to which the JLS refers, but without explicit
> documentation of such it's a fragile promise/premise.

Quite so!

tom

--
Tubes are the foul subterranean entrails of the London beast, stuffed
with the day's foetid offerings. -- Tokugawa

Tom Anderson

unread,
Nov 19, 2009, 4:03:39 PM11/19/09
to
On Wed, 18 Nov 2009, Alessio Stalla wrote:

> On 18 Nov, 20:06, Tom Anderson <t...@urchin.earth.li> wrote:
>
>> What's really happening is more like this:
>>
>> class FooMangler implements Mangler {
>> � � � � static {
>> � � � � � � � � ManglerRegistry.register("foo", FooMangler.class);

>> � � � � }


>>
>> }
>
> If you have control on the source code of the mangler, I would do like
> this:
>
> class FooMangler implements Mangler {
> public static void autoregister() {}
> ...
> }
>
> and to initialize it, FooMangler.autoregister();

We have indeed done it like that in similar situations. I can't remember
why we didn't do it like that here - i think someone didn't like the idea
of having a method which 'did nothing'. I'll mention this to my colleagues
when we next pass by this bit of code.

tom

--
Safety Not Guaranteed

Tom Anderson

unread,
Nov 19, 2009, 4:05:45 PM11/19/09
to
On Wed, 18 Nov 2009, Arne Vajh?j wrote:

> Tom Anderson wrote:
>
>> Am i right in thinking that all of these will force loading of Foo? Does
>> anyone have any other idioms? How about any opinions on which idiom is
>> best, or at least most idiomatic?
>
> I don't think the problem is common enough to make a solution idiomatic.

It seems not.

> I would without thinking twice:
> - read class names from config file
> - use Class.forName to initialize them

The set of classes that need loading is very much static and code-like; it
isn't the kind of thing that *needs* configuration at runtime. Given that,
is reading a file really the right thing to do? How about putting the
names in a string array?

Tom Anderson

unread,
Nov 19, 2009, 4:09:41 PM11/19/09
to
On Wed, 18 Nov 2009, Kevin McMurtrie wrote:

> Self-registering classes are not the best design. Under extremely rare
> circumstances, references from live classes to the registration
> container might not exist during a GC - then it's suddenly empty. In a
> web server or other application with multiple ClassLoaders, it might not
> be clear where things are going. For the work I've done, there were
> enough problems to justify not using JDBC driver self-registration with
> DriverManager.
>
> Consider a configuration parameter that is a list of classes that your
> registration container should load when it initializes.

Sadly, the registration container is third-party, and i can't change it.

Annoyingly, the system it's in has a dependency injection framework with a
nice layering mechanism that lets modules we build add to the
configuration of components defined by others. If the container was a
component in this framework, adding classes to its to-do list would be as
simple as putting their names in a file. But it isn't!

Tom Anderson

unread,
Nov 19, 2009, 4:11:39 PM11/19/09
to
On Thu, 19 Nov 2009, Jim Janney wrote:

> Tom Anderson <tw...@urchin.earth.li> writes:
>
>> class FooMangler implements Mangler {
>> static {
>> ManglerRegistry.register("foo", FooMangler.class);
>> }
>> }
>

> To me what smells here is that ManglerRegistry is using static methods.
> I'd prefer creating an instance of ManglerRegistry, registering the
> appropriate manglers with it, and keeping a reference to it in the
> ManglingParser. This requires more coding, obviously, but gives you
> more flexibility in that different parsers can use different registries.

You're absolutely right, of course, and if i was in charge, that's how it
would be done. Sadly, the ManglerRegistry is supplied by someone else,
their parsing code depends on it, and we need their parsing code. All very
annoying.

Little Green Man

unread,
Nov 19, 2009, 4:31:21 PM11/19/09
to
On Nov 19, 4:11 pm, Tom Anderson <t...@urchin.earth.li> wrote:
> You're absolutely right, of course, and if i was in charge, that's how it
> would be done. Sadly, the ManglerRegistry is supplied by someone else,
> their parsing code depends on it, and we need their parsing code. All very
> annoying.

Consider shopping around for an alternative that does the same job.
Preferably open source.

Jim Janney

unread,
Nov 19, 2009, 5:51:29 PM11/19/09
to
Tom Anderson <tw...@urchin.earth.li> writes:

Ah. In that case, I'd probably just get rid of the static blocks and
do the registration directly in your initializer: that is, change

void initialise() {
Class.forName(Foo.class.getName());
}

to

void initialise() {
ManglerRegistry.register("foo", FooMangler.class);
}


Since you have to reference each class in the initializer anyway, it
doesn't look as if the static blocks are buying you anything.

--
Jim Janney

Lew

unread,
Nov 19, 2009, 6:12:15 PM11/19/09
to
Jim Janney wrote:
> Ah.  In that case, I'd probably just get rid of the static blocks and
> do the registration directly in your initializer: that is, change
>
> void initialise() {
>         Class.forName(Foo.class.getName());
>
> }
>
> to
>
> void initialise() {
>         ManglerRegistry.register("foo", FooMangler.class);
>

Did you mean'Foo.class'?

> }
>
> Since you have to reference each class in the initializer anyway, it
> doesn't look as if the static blocks are buying you anything.
>

As pointed out upthread a couple of times, merely referencing the
'class' literal will not initialize the 'FooMangler' class. Since
tom's goal is to initialize the classes that are being registered,
your suggestion will not work unless the 'ManglerRegistry.register()'
call invokes a method in 'FooMangler' or does one of the other things
that initializes the class, some of which have been suggested in this
conversation already.

--
Lew

Dangling Pointer

unread,
Nov 19, 2009, 7:13:39 PM11/19/09
to
On Nov 19, 6:12 pm, Lew <l...@lewscanon.com> wrote:
> Jim Janney wrote:
> > Ah. In that case, I'd probably just get rid of the static blocks and
> > do the registration directly in your initializer: that is, change
>
> > void initialise() {
> > Class.forName(Foo.class.getName());
>
> > }
>
> > to
>
> > void initialise() {
> > ManglerRegistry.register("foo", FooMangler.class);
>
> Did you mean'Foo.class'?
>
> > }
>
> > Since you have to reference each class in the initializer anyway, it
> > doesn't look as if the static blocks are buying you anything.
>
> As pointed out upthread a couple of times, merely referencing the
> 'class' literal will not initialize the 'FooMangler' class. Since
> tom's goal is to initialize the classes that are being registered

The goal was to register the classes. Tom wanted to initialize the
classes because doing so would make them self-register, but if they
can be registered directly, so much the better (as long as
registration is idempotent, so subsequent initialization of the
classes doesn't cause some sort of problems via "double
registration").

Of course, this depends on the apparently-closed-source API he's using
exposing a manual registration method, as well as on idempotency of
registration.

Arne Vajhøj

unread,
Nov 19, 2009, 7:56:38 PM11/19/09
to

I would use the file.

If your code will be used in 20 years, then I think there
is a decent chance that someone will want to reconfigure
at some point in time.

Arne

Jim Janney

unread,
Nov 19, 2009, 11:43:02 PM11/19/09
to
Dangling Pointer <dpoi...@gmail.com> writes:

Exactly. I'm assuming that

ManglerRegistry.register(String tag, Class<? extends Mangler> manglerClass)

(or whatever) simply sticks the class into a hashmap until the XML
parser encounters the appropriate tag, whereupon an instance of the
mangler is created through reflection. I've written similar code for
other SAX-based parsers. This approach is arguably superior in that
the class isn't initialized until it's actually needed -- which may
not happen at all.

--
Jim Janney


Tom Anderson

unread,
Nov 20, 2009, 12:20:18 PM11/20/09
to

Believe me, i am constantly on the lookout for just that.

The trouble is that this Mangler business is not a standalone thing. It's
just one tentacle of a vast and terrifying tentacle-monster. There's no
way to replace tentacles bit by bit - we'd have to replace the whole
monster.

tom

--
If it ain't broke, open it up and see what makes it so bloody special.

Tom Anderson

unread,
Nov 20, 2009, 6:18:36 PM11/20/09
to

What i'm not keen on there is that the initialiser class has to know about
FooMangler's relationship with the ManglerRegistry. It doesn't seem like
any of its business to me.

tom

--
Work alone does not suffice: the efforts must be intelligent. -- Charles
B. Rogers

Филимон Лаковид

unread,
Nov 24, 2009, 7:04:39 AM11/24/09
to
To me what smells here is that ManglerRegistry is using static
methods. I'd prefer creating an instance of ManglerRegistry,
registering the appropriate manglers with it, and keeping a reference
to it in the ManglingParser. This requires more coding, obviously,
but gives you more flexibility in that different parsers can use

Arne Vajhøj

unread,
Nov 25, 2009, 10:42:05 PM11/25/09
to
Kevin McMurtrie wrote:
> Self-registering classes are not the best design. Under extremely rare
> circumstances, references from live classes to the registration
> container might not exist during a GC - then it's suddenly empty.

Any detail son that?

> Consider a configuration parameter that is a list of classes that your
> registration container should load when it initializes.

That was my suggestion as well.

Arne

Kevin McMurtrie

unread,
Nov 26, 2009, 2:25:33 AM11/26/09
to
In article <4b0df904$0$274$1472...@news.sunsite.dk>,

Arne Vajh�j <ar...@vajhoej.dk> wrote:

> Kevin McMurtrie wrote:
> > Self-registering classes are not the best design. Under extremely rare
> > circumstances, references from live classes to the registration
> > container might not exist during a GC - then it's suddenly empty.
>
> Any detail son that?

I witnessed it years ago in an early Java web server. There was about a
1 in 30 chance that the JDBC driver would initialize yet DriverManager
didn't have it. It turned out that because Reflection was used to run
startup components, there was a period of time with no reference to JDBC
classes or DriverManager. Intentionally holding some references until
after startup completed was the cure.

Sure, that's an example of a very rare and obscure bug. Unfortunately
they're the worst kind.


>
> > Consider a configuration parameter that is a list of classes that your
> > registration container should load when it initializes.
>
> That was my suggestion as well.
>
> Arne

Darth Kronos

unread,
Nov 26, 2009, 9:33:07 AM11/26/09
to
On Nov 26, 2:25 am, Kevin McMurtrie <mcmurt...@pixelmemory.us> wrote:
> Sure, that's an example of a very rare and obscure bug.  Unfortunately
> they're the worst kind.

test

Tom Anderson

unread,
Nov 26, 2009, 3:29:32 PM11/26/09
to

Good advice.

tom

--
IME the only lousy shags are when she says no! -- John Rowland

Tom Anderson

unread,
Nov 26, 2009, 4:21:24 PM11/26/09
to
On Wed, 25 Nov 2009, Kevin McMurtrie wrote:

> In article <4b0df904$0$274$1472...@news.sunsite.dk>,


> Arne Vajh?j <ar...@vajhoej.dk> wrote:
>
>> Kevin McMurtrie wrote:
>>> Self-registering classes are not the best design. Under extremely rare
>>> circumstances, references from live classes to the registration
>>> container might not exist during a GC - then it's suddenly empty.
>>
>> Any detail son that?
>
> I witnessed it years ago in an early Java web server. There was about a
> 1 in 30 chance that the JDBC driver would initialize yet DriverManager
> didn't have it. It turned out that because Reflection was used to run
> startup components, there was a period of time with no reference to JDBC
> classes or DriverManager. Intentionally holding some references until
> after startup completed was the cure.
>
> Sure, that's an example of a very rare and obscure bug. Unfortunately
> they're the worst kind.

ISTR they changed the rules about this at some point, 1.2 i think -
essentially, a class is referenced by and references its classloader, so a
class that's been loaded won't be unloaded until not only does it have no
instances or direct references, but all classes loaded by its classloader
are also in the same condition (and there are no references to the
classloader).

Now, of course, web servers and app servers tend to do clever tricks with
classloaders, in which case that can indeed happen. But DriverManager is a
standard library class, so it will be loaded by the bootstrap classloader,
which remains aloof from these shenanigans, and will never be
unreferenced. If a static variable in DriverManager refers to the driver
class, then it will never be unloaded.

(Right?)

0 new messages