Well, it's clear to me what's happening, for whatever that's worth.  I'm
sure it's clear to Jens too, but I'll summarize it anyway for the benefit of
the mail archives, if nothing else.  Also, there's a possible solution
suggested below for Jens' specific problem.

Given an SPI interface, Axis's factory classes (which implement the
discovery-based search for implementations) tell the discovery system to use
the classloader that loaded that interface as the basis for the search.
This works if your implementations and their resources can be reached by the
same classloader that was used to load the corresponding service provider
interface, but not if the interfaces were loaded by a shared classloader
that cannot see the application-specific loader's resources & classes.

<workaround>
So, in the case of WSDDProvider, you must ensure that the classloader that
loads WSDDProvider can "see" all of the implementations of that service you
want to use.  If you put WSDDProvider into a parent classloader, your
application's implementations will go undiscovered.
</workaround>

For Jens situation, I think the "correct" behavior would be for WSDDProvider
to not use its own classloader as the basis of discovery.  Rather, it should
use Thread.currentThread().getContextClassLoader().  Better still, it should
let the Discovery API provide a "complete" loader that will search in all of
the "right" places for an application:

This static method on the discovery ClassLoaders class will produce a
ClassLoaders instance that contains the Thread's context loader, the loaders
of the spi, the factory, and the system classloader, with the option of
searching ancestor loaders too.  This is surely the right thing to use in
WSDDProvider in place of WSDDProvider.class.getClassLoader();

public static ClassLoaders getAppLoaders(Class spi, Class factory, boolean
prune);

-----Original Message-----
From: Jens Schumann [mailto:[EMAIL PROTECTED]
Sent: Tuesday, March 25, 2003 1:58 PM
To: [EMAIL PROTECTED]
Subject: Re: what version of commons-discovery is being used in the
latest version?


On 3/25/03 08:55 PM [EMAIL PROTECTED]
<[EMAIL PROTECTED]> wrote:

> I assume you mean Thread.currentThread().getContextClassLoader().  That's
> *supposed* to work for this purpose, but it's not hard to believe that
there
> are problems between vendors.  What would happen if your application code
> set the thread's contextclassloader to be your servlet context class
loader?
> This is what your application server vendor is supposed to have done, but
if
> it isn't so, can you ...correct the problem?
> 
> I should also mention that I noticed that commons-discovery contains
support
> for passing in an object whose class' loader will be used as the basis of
> the search.  That might a useful way to make the behavior more
> deterministic.


(Yes, I was talking about Thread.currentThread().getContextClassLoader(),
looks like I get used to have the editor fix my syntax errors ;).


I don't know what commons discovery is doing, all I can say is that for
instance

 ClassLoader clzLoader = WSDDProvider.class.getClassLoader();
 ClassLoaders loaders = new ClassLoaders();
 loaders.put(clzLoader);
 DiscoverServiceNames dsn = new DiscoverServiceNames(loaders);
 ResourceNameIterator iter =
dsn.findResourceNames(PLUGABLE_PROVIDER_FILENAME);

does not work as expected (see WSDDProvider.java). Using an EAR Bea was
unable to find a resource (I put it in lib/some.jar and
classes/META-INF/..).

The reason is simple in my case: Bea uses an EJB Classloader to load a war
archive, and I have a common shared jar referenced from the ejb-jar and the
war archive in their Manifest.MF. A patched Axis Servlet is part of this
common jar, and thus said it will be loaded through the ejb classloader
directly. You might argue that I could split my jars easily. But this isn't
going to work. Build management for reusable j2ee components is a nightmare,
and the best way to resolve dependencies is using shared jars across
deployed war and ejb jar files ;)


Setting a context classloader could be a bad idea, it could really break the
app server, its thread pools and its resource access. It seems Axis already
does something like that, see "AXIS classloaders breaking J2EE application
isolation" on axis-user. I will try dig into that this evening ...

Jens


Reply via email to