You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Tom Amiro <To...@Sun.COM> on 2002/03/01 16:11:07 UTC

load-on-startup and finding external classes with Tomcat 4.x

Hi,

Situation: A Xalan servlet whose init method  creates a template 
for a stylesheet that references an external java class and does 
the transformation in a doGet method.

Problem: With Tomcat 4.x, if you configure the web.xml to load the
servlet at 
startup, when it runs, the external java class cannot be found. However, 
if you do not load on startup, when the server is first hit, the init 
method is invoked and the external java class is found and the
transformation 
works.

-- 
 Tom Amiro -- SQA Engineer
 Sun XML Technology Development
 voice: 781-442-0589 Fax: 781-442-1437
 eMail: tom.amiro@.sun.com

Re: load-on-startup and finding external classes with Tomcat 4.x - Good News

Posted by Tom Amiro <To...@Sun.COM>.
Hi All,

Good news! I can no longer get either Xalan nor XSLTC to have 
trouble finding external java classes with the latest Tomcat 
in the Sun's WSPACK EA2 promoted build 30, regardless of whether 
the servlets are loaded by Tomcat at startup or not. 

I did follow Gary P's suggestion to dump out the environment 
in the init and doGet methods and to get info on the class loaders 
in both init and doGet methods using this.getClass().getClassLoader().

The output showed that the WebappClassLoader was in effect 
and WEB-INF/classes was available in both the init and doGet 
-- so no suprise the external class there was found -- regardless 
of whether load-on-startup was in effect.

Don't know why I had a problem with Xalan before. I even 
tried the servlets with a doPost rather than doGet method
and still encountered no problems.

Tom

"Craig R. McClanahan" wrote:
> 
> Tom,
> 
> Your scenario should work, and the GetDay class should be visible.
> 
> I verified that this problem still happens in b29 of JWSDP.  From the
> stack trace, it sure looks like it's either a problem with XSLTC
> itself, or the code being generated for the transform, that is not
> calling Thread.currentThread().getContextClassLoader() correctly.
> Although why it matters whether the servlet is load-on-startup or not
> is pretty mysterious.
> 
> Looking inside theTransformerFactoryImpl.newTemplates() method, it
> throws the "Could not compile stylesheet" error because
> xsltc.compile() returns null, so it's probably something deep down
> inside the compiler.  One thing to double check is that nothing inside
> xsltc ever creates another thread to do some work -- if it does, then
> obviously the thread context class loader will not get set correctly
> for *that* thread, unless you copy the one from the initial thread.
> 
> I did a separate test and verified that the init() method of a
> load-on-startup servlet does indeed see the correct context class
> loader.    A very quick way to prove it would be to say:
> 
>   ClassLoader threadClassLoader =
> Thread.currentThread().getContextClassLoader();
>   Class getDayClass = threadClassLoader.loadClass("GetDay");
> 
> in the init() method of your test, and run it with load-on-startup
> set.
> 
> Craig
> 
> 
> Tom Amiro wrote:
> 
> > "Craig R. McClanahan" wrote:
> > >
> > > Tom Amiro wrote:
> > >
> > > > Hi,
> > > >
> > > > Situation: A Xalan servlet whose init method  creates a template
> >
> > > > for a stylesheet that references an external java class and does
> >
> > > > the transformation in a doGet method.
> > > >
> > > > Problem: With Tomcat 4.x, if you configure the web.xml to load
> > the
> > > > servlet at
> > > > startup, when it runs, the external java class cannot be found.
> > However,
> > > > if you do not load on startup, when the server is first hit, the
> > init
> > > > method is invoked and the external java class is found and the
> > > > transformation
> > > > works.
> > > >
> > >
> > > I'm going to do the classic "please give me a test case" response
> > :-).
> >
> > OK. Attached is xsltsmoke.tar. If you untar it in the .../webapps
> > directory then hit the servlet with
> >
> >
> > http://localhost:8080/xsltsmoke/XalanServlet?xsl=search.xsl&states=MA
> >
> > > But the
> > > most likely problem is that you've got some classes loaded from
> > within your
> > > webapp's /WEB-INF/lib or /WEB-INF/classes directory, and some from
> > a shared
> > > repository (such as the common/lib directory) which is loaded by a
> > different
> > > class loader.  It may be that your application is dependent on the
> > order in
> > > which the classes get loaded, which in turn might be affected by
> > whether your
> > > servlet is loaded initially or in response to a request (when some
> > of the
> > > classes in question might have been loaded by other activity in
> > the webapp).
> >
> > Is this a catch-22? I'm using WSPACK EA2 which comes with
> > xalan.jar in the .../wspack/common/endorsed directory. My little
> > servlet
> > test app has servlet classes and an external java class in the apps
> > WEB-INF/classes. Shouldn't I be able to roll my app up into a war
> > file
> > and
> > drop it into the wspack? It would break that model if I have to move
> >
> > any class I create into the .../common/endorsed directory.
> >
> > >
> > > Key rules to remember:
> > >
> > > * You should ensure that there is one and only one copy of any
> > particular
> > >   Java class anywhere in the server.
> > >
> > > * Classes that are loaded from Tomcat's shared or common class
> > loaders
> > >   (for instance, because the are in common/lib) do *not* have
> > direct access
> > >   to classes in the web app's class loader.  In other words, a
> > Class.forName()
> > >   call from here will get a class not found exception.  However,
> > you can
> > >   access the webapp's class loader like this:
> > >     ClassLoader webappClassLoader =
> > > Thread.currentThread().getContextClassLoader()
> > >   as long as you are within the context of a request.
> >
> > I believe Xalan is doing that within the request thread. Santiago
> > Perica-geertsen
> > was investigating how Xalan loads external java functions and told
> > me
> > that.
> > But if the init method is run when Tomcat loads, maybe the the
> > current
> > thread doesn't have access to the web apps class loader.
> >
> > Tom
> >
> > >
> > > >
> > > > --
> > > >  Tom Amiro -- SQA Engineer
> > > >  Sun XML Technology Development
> > > >  voice: 781-442-0589 Fax: 781-442-1437
> > > >  eMail: tom.amiro@.sun.com
> > >
> > > Craig
> >
> > --
> >  Tom Amiro -- SQA Engineer
> >  Sun XML Technology Development
> >  voice: 781-442-0589 Fax: 781-442-1437
> >  eMail: tom.amiro@.sun.com
> >
> >
> > --------------------------------------------------------------------------------
> >
> >                     Name: xsltsmoke.tar
> >    xsltsmoke.tar    Type: Unix Tape Archive (application/x-tar)
> >                 Encoding: base64

-- 
 Tom Amiro -- SQA Engineer
 Sun XML Technology Development
 voice: 781-442-0589 Fax: 781-442-1437
 eMail: tom.amiro@.sun.com

RE: load-on-startup and finding external classes with Tomcat 4.x

Posted by Gary L Peskin <ga...@firstech.com>.
Tom --

It sounds like the fully qualified external java class name (including
the classloader) is different depending on whether the init() method is
called by the load-on-startup routine or whether the init() method is
called upon first hit.

I would include the following statement in both the init() method and
the doGet() method immediately before the Xalan calls:

  System.err.println("My classloader is " +
this.class.getClassLoader());

I think that this will help in unraveling the mystery.  Also, you might
want to include a class to EnvironmentCheck and see what that reveals.

Are you using XSLTC or the traditional XalanJ?  What JDK version are you
using?

If you're unable to figure things out, please post all of the output
here and we'll get to the bottom of it.

Gary

> -----Original Message-----
> From: Tom.Amiro@Sun.COM [mailto:Tom.Amiro@Sun.COM] 
> Sent: Friday, March 01, 2002 7:11 AM
> To: xalan-dev@xml.apache.org
> Cc: craig mcclanahan
> Subject: load-on-startup and finding external classes with Tomcat 4.x
> 
> 
> Hi,
> 
> Situation: A Xalan servlet whose init method  creates a template 
> for a stylesheet that references an external java class and does 
> the transformation in a doGet method.
> 
> Problem: With Tomcat 4.x, if you configure the web.xml to 
> load the servlet at 
> startup, when it runs, the external java class cannot be 
> found. However, 
> if you do not load on startup, when the server is first hit, the init 
> method is invoked and the external java class is found and 
> the transformation 
> works.
> 
> -- 
>  Tom Amiro -- SQA Engineer
>  Sun XML Technology Development
>  voice: 781-442-0589 Fax: 781-442-1437
>  eMail: tom.amiro@.sun.com
>