powered by Jive Software

Why 3 ClassLoaders in the ProviderManager class?

Hello,

While porting my Java application to older/restricted VMs, I turned out that I got a problem with the 3 ClassLoaders used in the ProviderManager class.

Is there a reason for needing 3 Class loader for simply loading a text file?

Vincentoo

Vincentoo,

The ProviderManager class doesn’‘t actually create three class loaders, but just loads references to three. We’'ve found that trying to load resources from multiple class loaders has the best chance of working in different Java environments (desktop app, J2EE, applet, etc).

Is there different behavior that would work better for you?

Regards,

Matt

Hello Matt,

Is there different behavior that would work better for you?

Yes!

I understand your point, but if you look “backward”, to previous version of Java (such as JDK 1.1), this part of the code can not work since some APIs such as Thread.getContextClassLoader() and ClassLoader.getSystemClassLoader() do not exist yet; using the code as it is at the moment simply “crashes” the VM since these methods do not exist

Vincentoo

Vincentoo,

Smack doesn’‘t support JDK 1.1. If you’'re doing a backport yourself, can I suggest just removing that code for your own environment?

Regards,

Matt

Hello,

+Smack doesn’‘t support JDK 1.1. If you’'re doing a backport yourself, can I suggest just removing that code for your own environment?

Of course…

But for your information, with a JDK 1.1 with very minor Java 2 extensions, Smack works.

The most difficult part of the problem was tracing the source of it… Indeed there is a try / catch that does not report anything and was silently hidding the problem on my platform. In my opinion, a stack trace printing would be a good idead there (hint hint. ).

So far, the following changes were sufficient for me:

1)SmackConfiguration.java:

static {

try {

// Get an array of class loaders to try loading the providers files from.

ClassLoader[] classLoaders = getClassLoaders();

for (int i = 0; i < classLoaders.length; i++) {

Enumeration configEnum = null;

if(classLoaders+ != null) {

configEnum = classLoaders+.getResources(“META-INF/smack-config.xml”);

} else {

Vector urls = new Vector(1);

urls.add(ClassLoader.getSystemResource(“META-INF/smack-config.xml”));

configEnum = urls.elements();

}

while (configEnum.hasMoreElements()) {

private static ClassLoader[] getClassLoaders() {

ClassLoader[] classLoaders = new ClassLoader[3];

classLoaders[0] = new SmackConfiguration().getClass().getClassLoader();

try {

classLoaders[1] = Thread.currentThread().getContextClassLoader();

} catch(NoSuchMethodError e1) {}

try {

classLoaders[2] = ClassLoader.getSystemClassLoader();

} catch(NoSuchMethodError e2) {}

return classLoaders;

}

  1. ProviderManager.java

Same kind of changes (in the static block and in the getClassLoaders() method).

Vincentoo