Idiom for forcing class loading?

A

Arne Vajhøj

Tom said:
It seems not.


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?

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
 
J

Jim Janney

Dangling Pointer said:
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.

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

Tom Anderson

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

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
 
T

Tom Anderson

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.

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
 
Ä

ÄØÛØÜÞÝ »ÐÚÞÒØÔ

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

Arne Vajhøj

Kevin said:
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
 
K

Kevin McMurtrie

Arne Vajhøj said:
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.
 
T

Tom Anderson

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

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top