You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Jens Schumann <je...@void.fm> on 2003/03/02 23:31:56 UTC

Bug 17347 - Provider Lookup Fails within EARs

As stated in #17347 in certain situations the current custom provider lookup
will fail. I believe there is no way of having a cross app server jar based
resource loader, correct me if I am wrong. I have seen completely different
behaviors for exploded or archive based WAR or EAR deployments, even on the
same application server. Worst case some classes will be loaded using the
system classloader. In these cases you will never be able to access to the
WEB archive classpath, unless you use servletContext.getResource ...

One possible way to handle this may be adding a new <provider name=""
type="" /> tag to server-config.wsdd and call registerProvider(QName uri,
WSDDProvider prov) directly while reading the configuration.

If this is OK I will propose a patch ASAP.

Jens

PS: There are a few other areas in AXIS which require exploded deployment.
In my opinion a pretty nasty requirement ;(.


Classloader and Axis Caching . was: Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Jens Schumann <je...@void.fm>.
On 3/3/03 10:59 PM Steve Loughran <st...@iseran.com> wrote:

> 
> ----- Original Message -----
> From: "Jens Schumann" <je...@void.fm>
> To: <ax...@ws.apache.org>
> Sent: Monday, March 03, 2003 13:36
> Subject: Re: Bug 17347 - Provider Lookup Fails within EARs


 
> I havent heard of anyone trying to do >1 engine per webapp; you can always
> multi-webapp if that is needed. We have to cache the engine somewhere, and
> its either a static variable, a JMX registration or a servlet context, and
> since we dont support JMX, servlet contexts are what you get (though I would
> like to also register the engine in JMX).

So you probably talk to the first person;). The framework we are using for
our internal purposes separates the access/rendering technology from the
actual business logic completely. Apart from the typical WEB/WAP
environments we are able to support several SOAP implementations /
configurations in parallel, using the same business logic behind. At the
moment we don't need multiple Axis Instances at the same time, but I believe
we will need it. The problem is that the current AxisBaseServlet prevents
own AxisServlet caching strategies - too many private methods.

> 
> The trouble with servlet contexts is what will we do when we start
> supporting other transports more seriously? we have dependencies on servlets
> deep into Axis, which is mixing layers too closely for my liking

After looking through the sources last week I doubt it will that easy to get
rid of those dependencies;).

The static accessor you suggested is one way to go, and we/I have chosen
this strategy a couple times. It looks like a dirty workaround, but we add
required references depending on the environment. The internal lookup tree
handles everything else.

Maybe we should take a look at the different transport mechanism too. In the
end I believe there will always be a JSP/Servlet container available, apart
from standalone applications. (If I remember correctly Axis makes heavy use
of reflection, which prevents usage inside of EJB. But, I don't know how to
solve certain issues without reflection ;)

Jens


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: "Jens Schumann" <je...@void.fm>
To: <ax...@ws.apache.org>
Sent: Monday, March 03, 2003 13:36
Subject: Re: Bug 17347 - Provider Lookup Fails within EARs




>> The problem is choosing which classloader to use. We could consider
>> standardising on ServletContext.getResourceAsStream(), as it doesnt have
to
>> be a classloader at all. Or we have a method
>> AxisEngine.getResourceAsStream(String path) that tries the ServletContext
>> call first, then its own classloader if that fails to find resources. At
the
>> very least, it would give us a single place to instrument and toy with
when
>> trying to fix future problems.
>

>That¹s exactly what I am looking for. I could spend another 10 pages about
>classloaders in EARs/WAR archives - using ServletContext.getResource() or
>ServletContext.getResourceAsStream() solved all those problems. I don't
want
>to mix up things here, but be aware that some people need to be able to
have
>multiple AxisEngines within one WAR, something which does not work right
now
>(because one AxisServer instance is "cached" in the servlet context). So
>whatever we do to fix classloading, it should not prevent this setup.

I havent heard of anyone trying to do >1 engine per webapp; you can always
multi-webapp if that is needed. We have to cache the engine somewhere, and
its either a static variable, a JMX registration or a servlet context, and
since we dont support JMX, servlet contexts are what you get (though I would
like to also register the engine in JMX).

The trouble with servlet contexts is what will we do when we start
supporting other transports more seriously? we have dependencies on servlets
deep into Axis, which is mixing layers too closely for my liking


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Jens Schumann <je...@void.fm>.
On 3/3/03 09:31 PM Steve Loughran <st...@iseran.com> wrote:
 
> dont do that then :) CLASSPATH should be empty. And axis must never go into
> JRE/ext. If people mess with the classpath outside the webapp then its their
> own faulut.

Hehe. Yes - its a don't do. But I have seen it several times.

> hmmm. That does sound wierd. File a bug with axis and jboss.

If I find the time to nail down the problem ;)
 
> The problem is choosing which classloader to use. We could consider
> standardising on ServletContext.getResourceAsStream(), as it doesnt have to
> be a classloader at all. Or we have a method
> AxisEngine.getResourceAsStream(String path) that tries the ServletContext
> call first, then its own classloader if that fails to find resources. At the
> very least, it would give us a single place to instrument and toy with when
> trying to fix future problems.
> 

That¹s exactly what I am looking for. I could spend another 10 pages about
classloaders in EARs/WAR archives - using ServletContext.getResource() or
ServletContext.getResourceAsStream() solved all those problems. I don't want
to mix up things here, but be aware that some people need to be able to have
multiple AxisEngines within one WAR, something which does not work right now
(because one AxisServer instance is "cached" in the servlet context). So
whatever we do to fix classloading, it should not prevent this setup.

Jens


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: "Jens Schumann" <je...@void.fm>
To: <ax...@ws.apache.org>
Sent: Monday, March 03, 2003 11:26
Subject: Re: Bug 17347 - Provider Lookup Fails within EARs


> On 3/3/03 06:14 PM Steve Loughran <st...@iseran.com> wrote:
>
> >
> > ooh, first we have to enum the problems with different platforms.
> >
> > Tomcat: endorsed versus non-endorsed dirs on java1.4
> > SunOne: recent postings about its contextClassloader being invalid
> > WebLogic: doesnt explode WARs into directories, so whenever we ask for
the
> > physical path to something in the webapp, we get failure.
>
> Hmm.
> I think we should to take a look at classloader hierarchies found on these
> platforms first. (I might be a little bit off the actual implementation -
> since I am writing this out of my head).

>
> So why did I spend that much time explaining class loading mechanisms? ;)
> Because I would show that there is nothing you can be sure of while
calling
> getClass().getClassLoader() or currentThread().getContextClassLoader().

yup. Also there is ServletContext.getResource() and
ServletContext.getResourceAsStream() to worry about.

>
> If somehow someone put axis.jar in the system classpath and uses weblogic
or
> websphere, it will be tough to access a resource inside the war.

dont do that then :) CLASSPATH should be empty. And axis must never go into
JRE/ext. If people mess with the classpath outside the webapp then its their
own faulut.

>Same
> applies to referenced modules inside Websphere. Ear deployment on bea 6.x
> will force you in certain situations to reference or add all war archive
> classes to all ejb archives, otherwise you will run into
> ClassNotFoundExceptions.

> But - this also means that your this classes will
> be loaded by the EAR classloader, not through the war archive classloader.
I
> don't know why, but using the exploded axis web archive on JBoss forced me
> to copy the servlet classes in its WEB-INF/lib, otherwise usage of the
admin
> servlet would fail. But servlet classes are part of lib/ and should be
> accessible through the shared repository.

hmmm. That does sound wierd. File a bug with axis and jboss.

>
> So what do I recommend? Avoid using getClassloader().getResource() in web
> archives at all ;).

I find it has a useful place. I keep a lot of my config stuff in the WAR,
and dont encounter your problems. Example: Axis1.1 lets you provide the path
to the WSDL resource for the ?wsdl response.

The problem is choosing which classloader to use. We could consider
standardising on ServletContext.getResourceAsStream(), as it doesnt have to
be a classloader at all. Or we have a method
AxisEngine.getResourceAsStream(String path) that tries the ServletContext
call first, then its own classloader if that fails to find resources. At the
very least, it would give us a single place to instrument and toy with when
trying to fix future problems.


> And btw - hot redeployment and JNDI object registration
> makes things much worse ;).

yes, there is nothing like an old object instance being serialised somewhere
to hurt you.


> > Attachments can be configured to go somewhere else, I believe
> Yes, but default will be inside the war.

that should be fixed. Even if we fix class loading, we should eliminate
writing to the war space.


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Jens Schumann <je...@void.fm>.
On 3/3/03 06:14 PM Steve Loughran <st...@iseran.com> wrote:

> 
> ooh, first we have to enum the problems with different platforms.
> 
> Tomcat: endorsed versus non-endorsed dirs on java1.4
> SunOne: recent postings about its contextClassloader being invalid
> WebLogic: doesnt explode WARs into directories, so whenever we ask for the
> physical path to something in the webapp, we get failure.

Hmm.
I think we should to take a look at classloader hierarchies found on these
platforms first. (I might be a little bit off the actual implementation -
since I am writing this out of my head).

Assuming EAR deployment Bea 6.x will create one EAR classloader (a child of
the system classloader) to load all ejb-jars in the EAR. For every .war
archive in this EAR a child of the EAR classloader will be created. If you
deploy war and ejb archives separately, one classloader (also a child of the
system classloader) will be created for every J2EE component.

Websphere 4.x is a little bit more complex, since it introduces the concept
of visibility for classloaders. I can't remember all details, but I know
there is one mode similar to the EAR deployment from weblogic, and another
one with "module" visibility. In this case all modules (war, ejb-jar and
Manifest Classpath entries) are loaded by a different classloader. Manifest
entries will make this more complex: The classloader of the jar containing a
Manifest reference will act as a child of the classloader which is
responsible for the referenced jar. In all cases these classloaders are
child's of the system classloader. (Btw. there are two other modes left).

JBoss on the other hand separates the system classloader and its own boot
classloader(s) strictly from the server instance classloaders - only a few
system classes are accessible to it. The core server deployment and
classloading infrastructure of Jboss is made of three parts: A
UnifiedClassloader, a shared class repository and deployers. JBoss removes
the standard parent delegation model in favour of the shared repository. To
make things short - apart from the EAR deployer all other deployers will
make their resources accessible through this shared repository. The EAR
deployer creates its own class repository (for its resources) and delegates
load requests only in case it does not find the given resource.

JRun behaves pretty similar to JBoss, since it uses the same JMX kernel.

So why did I spend that much time explaining class loading mechanisms? ;)
Because I would show that there is nothing you can be sure of while calling
getClass().getClassLoader() or currentThread().getContextClassLoader().

If somehow someone put axis.jar in the system classpath and uses weblogic or
websphere, it will be tough to access a resource inside the war. Same
applies to referenced modules inside Websphere. Ear deployment on bea 6.x
will force you in certain situations to reference or add all war archive
classes to all ejb archives, otherwise you will run into
ClassNotFoundExceptions. But - this also means that your this classes will
be loaded by the EAR classloader, not through the war archive classloader. I
don't know why, but using the exploded axis web archive on JBoss forced me
to copy the servlet classes in its WEB-INF/lib, otherwise usage of the admin
servlet would fail. But servlet classes are part of lib/ and should be
accessible through the shared repository.

So what do I recommend? Avoid using getClassloader().getResource() in web
archives at all ;). And btw - hot redeployment and JNDI object registration
makes things much worse ;).

(I haven't examined Orionserver/Oracle IAS and Pramati Server classloader
details, but I haven't had classloader issues apart from struts, earlier
versions). 

...
 


> Attachments can be configured to go somewhere else, I believe
Yes, but default will be inside the war.

Jens




Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: "Jens Schumann" <je...@void.fm>
To: <ax...@ws.apache.org>
Sent: Monday, March 03, 2003 01:10
Subject: Re: Bug 17347 - Provider Lookup Fails within EARs


> On 3/3/03 04:08 AM Steve Loughran <st...@iseran.com> wrote:
>
> >
> > ----- Original Message -----
> > From: "Jens Schumann" <je...@void.fm>
> > To: <ax...@ws.apache.org>
> > Sent: Sunday, March 02, 2003 14:31
> > Subject: Bug 17347 - Provider Lookup Fails within EARs
> >
> > I would encourage spending time getting it right (including discussing
> > proposals on the mail list), rather than rushing out a patch, as it is
> > pretty unlikely it is going to get into Axis1.1 this late  in the game.
> >
> > First step should be we need to enumerate the different classloader
problems
> > we are encoutering, across the various popular app servers people use.
>
> OK. How should we proceed?

ooh, first we have to enum the problems with different platforms.

Tomcat: endorsed versus non-endorsed dirs on java1.4
SunOne: recent postings about its contextClassloader being invalid
WebLogic: doesnt explode WARs into directories, so whenever we ask for the
physical path to something in the webapp, we get failure.

>
> >
> > Agreed. We need to look at config persistence better.
>
> Basically everything which is placed inside of an war archive during
runtime
> isn't doing anything good. Attachments for instance.

Attachments can be configured to go somewhere else, I believe

>
> Honestly, I haven't deployed a single exploded war archive in production
> quite a long time, usually we deploy everything as EAR. If you look at
> typical admin server - cluster nodes deployments (as used in BEA clusters)
> you will run into serious problems while updating something in your .war
> archive on a single node.
>
>
> > FYI my laptops' Axis source has a 'deploy on startup servlet' that
> > auto-registers an array of .wsdd  files, so you dont need config
persistence
> > so much; it autoinits itself from the build time configuration every
startup
>
> Yes. The init servlet approach. In my opinion this should be part of
> initializing the AxisServer instance. The current admin servlet is a
really
> nice tool for development, but nothing I would use nor allow in
production.
> Thus, persistence isn't required anyway (in production).

I agree. Though I am also biased towards something like an LDAP server in
production, for instant configuration of a whole cluster.


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Jens Schumann <je...@void.fm>.
On 3/3/03 04:08 AM Steve Loughran <st...@iseran.com> wrote:

> 
> ----- Original Message -----
> From: "Jens Schumann" <je...@void.fm>
> To: <ax...@ws.apache.org>
> Sent: Sunday, March 02, 2003 14:31
> Subject: Bug 17347 - Provider Lookup Fails within EARs
> 
> I would encourage spending time getting it right (including discussing
> proposals on the mail list), rather than rushing out a patch, as it is
> pretty unlikely it is going to get into Axis1.1 this late  in the game.
> 
> First step should be we need to enumerate the different classloader problems
> we are encoutering, across the various popular app servers people use.

OK. How should we proceed?

> 
> Agreed. We need to look at config persistence better.

Basically everything which is placed inside of an war archive during runtime
isn't doing anything good. Attachments for instance.

Honestly, I haven't deployed a single exploded war archive in production
quite a long time, usually we deploy everything as EAR. If you look at
typical admin server - cluster nodes deployments (as used in BEA clusters)
you will run into serious problems while updating something in your .war
archive on a single node.


> FYI my laptops' Axis source has a 'deploy on startup servlet' that
> auto-registers an array of .wsdd  files, so you dont need config persistence
> so much; it autoinits itself from the build time configuration every startup

Yes. The init servlet approach. In my opinion this should be part of
initializing the AxisServer instance. The current admin servlet is a really
nice tool for development, but nothing I would use nor allow in production.
Thus, persistence isn't required anyway (in production).


Jens


Re: Bug 17347 - Provider Lookup Fails within EARs

Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: "Jens Schumann" <je...@void.fm>
To: <ax...@ws.apache.org>
Sent: Sunday, March 02, 2003 14:31
Subject: Bug 17347 - Provider Lookup Fails within EARs


> As stated in #17347 in certain situations the current custom provider
lookup
> will fail. I believe there is no way of having a cross app server jar
based
> resource loader, correct me if I am wrong. I have seen completely
different
> behaviors for exploded or archive based WAR or EAR deployments, even on
the
> same application server. Worst case some classes will be loaded using the
> system classloader. In these cases you will never be able to access to the
> WEB archive classpath, unless you use servletContext.getResource ...
>
> One possible way to handle this may be adding a new <provider name=""
> type="" /> tag to server-config.wsdd and call registerProvider(QName uri,
> WSDDProvider prov) directly while reading the configuration.
>
> If this is OK I will propose a patch ASAP.

I would encourage spending time getting it right (including discussing
proposals on the mail list), rather than rushing out a patch, as it is
pretty unlikely it is going to get into Axis1.1 this late  in the game.

First step should be we need to enumerate the different classloader problems
we are encoutering, across the various popular app servers people use.

> PS: There are a few other areas in AXIS which require exploded deployment.
> In my opinion a pretty nasty requirement ;(.

Agreed. We need to look at config persistence better.

FYI my laptops' Axis source has a 'deploy on startup servlet' that
auto-registers an array of .wsdd  files, so you dont need config persistence
so much; it autoinits itself from the build time configuration every startup