On Wed, 30 May 2001, Scott Sanders wrote:
> Craig will correct me if I am wrong, but the idea is that in a server
> environment, the server container *may* set the conxtext class loader
> for you (at the webapp level, presumably). I am under the assumption
> that this is done so that you can completly seal one webapp off from
> another at a class access level.
>
That's part of it. The other reason is that it allows the digester code
itself to be loaded from a shared classloader, but still create user
objects from the thread context class loader. In a servlet environment,
that would mean the class loader associated with your web app, so it would
have access to /WEB-INF/classes and /WEB-INF/lib.
However, the argument to do this unilaterally is much weaker when you take
Digester out of its original home (Struts, which was by definition
interested only in a web application world) and propose it as a general
purpose class library. Maybe we should have a boolean property to define
whether it does this or not? I think defaulting to true would be fine --
but people should be able to turn it off if their environment sets the
thread context class loader to something not useful.
> We changed the code to check for the context class loader first,
> assuming that would be better from a security perspective.
>
> Scott Sanders
>
Craig
> Jeff Turner wrote:
>
> > Hi,
> >
> > I'm curious as to why the Digester code always tries to use the thread's
> > classloader:
> >
> > ClassLoader ctxLoader = Thread.currentThread().getContextClassLoader();
> > if (ctxLoader == null) {
> > paramTypes[0] =
> > Class.forName(paramType);
> > } else {
> > paramTypes[0]
> > =
> > ctxLoader.loadClass(paramType);
> > }
> >
> > I'm pretty ignorant of classloaders in general. If anyone has pointers on this
> > subject, perhaps suggesting why the above is needed, it would be appreciated.
> >
> >
> > The reason I'm asking is because when I use Digester from within a
> > servlet, it fails silently. I have (laboriously) traced the problem down to the
> > fact that Digester uses the thread's classloader. If I remove the above checks,
> > and just have Class.forName(), my code (as follows) works:
> >
> > Digester digester = new Digester();
> > digester.push(this); // note: "this" is the servlet
> > digester.setDebug(9);
> > digester.setValidating(false);
> > // set rules
> >
> > digester.addObjectCreate("services/service",
>"net.socialchange.bob.AbstractService"); // this fails silently
> > digester.addSetProperties("services/service");
> > digester.addSetNext("services/service", "addService",
>"net.socialchange.bob.Service"); // as does this
> > // do parse
> >
> > My XML is:
> >
> > <services>
> > <service name="Service 1" URL="http://localhost:8090/bob3/serv1.jsp"/>
> > <service name="Service 2" URL="/serv2.jsp"/>
> > </services>
> >
> > I'm using tc3.2.2b5, jdk1.3, no securitymanager, latest Digester from CVS.
> >
> > If this sounds like a bug (in tomcat or Digester), rather than my ignorance,
> > I'll make a test case and file a proper bug report.
> >
> > thanks,
> >
> > --Jeff
>
>
>