The problem in your case is that the ParserFactory will be loaded by the
tomcat's classloader, and that classloader doesn't know about the child
class loader.

What you can do is: 

Class c=Class.forName( parserClass );
sXMLParser=c.newInstance();

That will load the parserClass using the servlet ( webapp ) class loader.

The problem will be fixed in 3.3, but it's too big ( and dangerous )
change to make in 3.2. 

Same thing used to happen with JNDI.

Ther is a JDK1.2 specific solution - using the Thread's class loader -
but tomcat must be backward compatible with JDK1.1 and org.xml.sax is also
JDK1.1 comptatible, so it can't use this API.

BTW, for JNDI to work you need to enable the JDK1.2
interceptor. Unfortunately that will not solve the parser problem because
SAX ParserFactory doesn't take advantage of the thread class loader.

Costin


> The parts of the code that loads the parser from
> my init() method:
> import org.xml.sax.Parser;
> import org.xml.sax.helpers.ParserFactory;
> 
>     private static final String PARAM_XML_PARSER            = "xmlParser";
>     private static Parser           sXMLParser;
> 
>             if (parserClass != null)
>                 sXMLParser = ParserFactory.makeParser(parserClass);
>             else
>                 sXMLParser = ParserFactory.makeParser();
> 
> And the stack trace I get with this configuration:
> java.lang.ClassNotFoundException: com.ibm.xml.parsers.DOMParser
>     at java.lang.Throwable.<init>(Throwable.java:96)
>     at java.lang.Exception.<init>(Exception.java:44)
>     at
> java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:71)
>     at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
>     at java.lang.ClassLoader.loadClass(ClassLoader.java:325)
>     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:380)
>     at java.lang.ClassLoader.loadClass(ClassLoader.java:257)
>     at java.lang.Class.forName1(Native Method)
>     at java.lang.Class.forName(Class.java:134)
>     at org.xml.sax.helpers.ParserFactory.makeParser(ParserFactory.java:129)
>     at com.tenzing.servlet.InitServlet.setXMLParser(InitServlet.java:331)
>     at
> com.tenzing.servlet.InitServlet.initializeConfiguration(InitServlet.java:298
> )
>     at com.tenzing.servlet.InitServlet.init(InitServlet.java:181)
>     at org.apache.tomcat.core.ServletWrapper.doInit(ServletWrapper.java:317)
>     at org.apache.tomcat.core.Handler.init(Handler.java:215)
>     at org.apache.tomcat.core.ServletWrapper.init(ServletWrapper.java:296)
>     at
> org.apache.tomcat.context.LoadOnStartupInterceptor.contextInit(LoadOnStartup
> Interceptor.java:130)
>     at
> org.apache.tomcat.core.ContextManager.initContext(ContextManager.java:491)
>     at org.apache.tomcat.core.ContextManager.init(ContextManager.java:453)
>     at org.apache.tomcat.startup.Tomcat.execute(Tomcat.java:195)
>     at org.apache.tomcat.startup.Tomcat.main(Tomcat.java:235)
> 
> 
> Could you suggest anything else?
> 
> Thanks again,
> 
> Aron.
> 
> 
> -----Original Message-----
> From: Rob Shaw [mailto:[EMAIL PROTECTED]]
> Sent: Tuesday, December 05, 2000 9:51 PM
> To: [EMAIL PROTECTED]
> Subject: Re: Class loading & classloader visibility test results
> 
> 
> Aron,
> 
> Based on the stack trace alone it's difficult to debug the problem.
> 
> If you want everything to be self contained within your context,
> then the first thing I would ensure is that every class required
> by your servlet is contained with the classes or lib directory
> of your context.
> 
> Also, since the system  classloader is used prior to your
> webapp's classloader, ensure that your system
> classpath is clean to avoid inadvertent loading of classes.
> 
> Ideally this is all you would have to do.
> 
> As a long shot, I've run into the following gotcha which may
> apply to xml4j.
> 
> I've run into problems with code that attempts to grab
> the current classloader in the following way: 
>     
>          Object object = new Object();
>          ClassLoader loader = object.getClass().getClassLoader();
> 
> I've found that the classloader retrieved in this manner is
> unable to load classes from within my context.  My rationale
> for this is because java.lang.Object is loaded and instantiated
> via the system classloader, and thus the system classloader is
> returned.
> Instead you want to do something like:
> 
>          ClassLoader loader = getClass().getClassLoader();
> 
> which should return your webapp's classloader.
> 
> Hopefully this helps.
> Rob
> 
> ----- Original Message ----- 
> From: "Aron Kramlik" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Tuesday, December 05, 2000 8:36 PM
> Subject: RE: Class loading & classloader visibility test results
> 
> 
> > Rob,
> > 
> > This is great information.  I wonder if you could explain
> > why it is that I need to put xml4j.jar file under the $CLASSPATH
> > (i.e. $TOMCAT_HOME/lib) that is loaded by an init() method of
> > a servlet?
> > 
> > Once I do this the class, com.ibm.xml.parsers.DOMParser, is found.
> > Stack trace below.
> > 
> > Anyh help would be much appreciated.
> > 
> > Thanks again for the great info,
> > Aron.
> > 
> > java.lang.ClassNotFoundException: com.ibm.xml.parsers.DOMParser
> >     at java.lang.Throwable.<init>(Throwable.java:96)
> >     at java.lang.Exception.<init>(Exception.java:44)
> >     at
> > java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:71)
> >     at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
> >     at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
> >     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:380)
> >     at java.lang.ClassLoader.loadClass(ClassLoader.java:257)
> >     at java.lang.Class.forName1(Native Method)
> >     at java.lang.Class.forName(Class.java:134)
> >     at
> org.xml.sax.helpers.ParserFactory.makeParser(ParserFactory.java:124)
> >     at com.tenzing.servlet.InitServlet.setXMLParser(InitServlet.java:331)
> >     at
> >
> com.tenzing.servlet.InitServlet.initializeConfiguration(InitServlet.java:298
> > )
> >     at com.tenzing.servlet.InitServlet.init(InitServlet.java:181)
> >     at
> org.apache.tomcat.core.ServletWrapper.doInit(ServletWrapper.java:317)
> > 
> > 
> > 
> > 
> > -----Original Message-----
> > From: Rob Shaw [mailto:[EMAIL PROTECTED]]
> > Sent: Tuesday, December 05, 2000 2:49 PM
> > To: [EMAIL PROTECTED]
> > Subject: Class loading & classloader visibility test results
> > 
> > 
> > For those that may be interested...
> > 
> > I was unclear as to how Tomcat was resolving class
> > loading and the visibility of classes to a context's
> > classloader so I created a simlpe test suite.
> > The test results are attached.
> > 
> > Rob Shaw
> > Servidium Inc.
> 


Reply via email to