You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Colin Sampaleanu <co...@bspark.com> on 2001/05/01 20:25:13 UTC

Bad classloading in Digester

There was never any reply to this message (below) I sent a few months ago
about a problem with the method used by the Digestor for class loading.

In a number of places, it uses the old style
	class.forName(name);
instead of the proper
	Thread.getCurrentThread.getContextClassLoader.loadClass(name);

The second form is _much_ preferred to the first, because the first will
potentially fail in any situation where there are multiple classloaders (one
owning the other), and the Digester is used in code loaded by both
classloaders (please see my original message for more details).

This kind of situation is very common any time you have something like a
server (web, etc.) with containers in it, each container having its own
classloader associated with it in order to handle code visibility and
versioning. Using the digester in this situation is not possible without
modifying the code to use the second form.

I am quite willing and able to upload patches to 4 digester files to fix
this, assuming they will be checked in by somebody. The only implication is
that the code will no longer run under JDK 1.1, but Struts already needs 1.2
in any case...

For more details on classloading issues in Java, here are a couple of
excellent white papers:
Understanclind Class.forName();
http://www.develop.com/downloads/DynLoad.zip
Exploiting the Java Virtual Machine:
http://www.develop.com/downloads/DevWPJav.pdf



> -----Original Message-----
> From: Colin Sampaleanu [mailto:colin@bspark.com]
> Sent: February 22, 2001 10:06 PM
> To: 'struts-dev@jakarta.apache.org'
> Subject: ClassLoader used in Digester
> 
> 
> We are currently using the digester in a server we build that 
> uses custom
> classloaders for some containers within it, which load custom apps.
> 
> We use the Digester in the server itself, and some of the 
> apps being loaded
> in the containers also want to use the Digester. The problem 
> is that when an
> app creates a Digester instance, it is created by the parent (system)
> classloader that loaded the server, since the server had 
> already used the
> Digester and that classloader knows about it. When the 
> Digester then does a
> Class.forName in one of its rules to create an object, it 
> knows nothing
> about the container's ClassLoader and the classes within it. 
> The class is
> only withing the app, and so can't be found.
> 
> Is there any downside to changing the Digester to always use:
>   Thread.getCurrentThread.getContextClassLoader.loadClass(name);
> instead of 
>   class.forName(name);
> 
> The code would no longer work in JDK 1.1, but that is already 
> the case...
> 

Re: Bad classloading in Digester

Posted by Scott Sanders <sa...@totalsync.com>.
Done in Digester in commons.  Thanks for the heads up Colin.

Scott

Craig R. McClanahan wrote:

> 
> On Tue, 1 May 2001, Scott Sanders wrote:
> 
> 
>> I can apply the patch to the code in jakarta-commons-sandbox as well.
>> 
>> I would assume that a dependency on JDK 1.2 is not a problem.  Someone 
>> will speak up if it is not.
>> 
> 
> 
> No, it's not a problem.  Struts requires 1.2 or later.
> 
> 
>> Scott
>> 
> 
> 
> Cragi
> 
> 
> 
>> Colin Sampaleanu wrote:
>> 
>> 
>>> There was never any reply to this message (below) I sent a few months ago
>>> about a problem with the method used by the Digestor for class loading.
>>> 
>>> In a number of places, it uses the old style
>>> 	class.forName(name);
>>> instead of the proper
>>> 	Thread.getCurrentThread.getContextClassLoader.loadClass(name);
>>> 
>>> The second form is _much_ preferred to the first, because the first will
>>> potentially fail in any situation where there are multiple classloaders (one
>>> owning the other), and the Digester is used in code loaded by both
>>> classloaders (please see my original message for more details).
>>> 
>>> This kind of situation is very common any time you have something like a
>>> server (web, etc.) with containers in it, each container having its own
>>> classloader associated with it in order to handle code visibility and
>>> versioning. Using the digester in this situation is not possible without
>>> modifying the code to use the second form.
>>> 
>>> I am quite willing and able to upload patches to 4 digester files to fix
>>> this, assuming they will be checked in by somebody. The only implication is
>>> that the code will no longer run under JDK 1.1, but Struts already needs 1.2
>>> in any case...
>>> 
>>> For more details on classloading issues in Java, here are a couple of
>>> excellent white papers:
>>> Understanclind Class.forName();
>>> http://www.develop.com/downloads/DynLoad.zip
>>> Exploiting the Java Virtual Machine:
>>> http://www.develop.com/downloads/DevWPJav.pdf
>>> 
>>> 
>>> 
>>> 
>>> 
>>>> -----Original Message-----
>>>> From: Colin Sampaleanu [mailto:colin@bspark.com]
>>>> Sent: February 22, 2001 10:06 PM
>>>> To: 'struts-dev@jakarta.apache.org'
>>>> Subject: ClassLoader used in Digester
>>>> 
>>>> 
>>>> We are currently using the digester in a server we build that 
>>>> uses custom
>>>> classloaders for some containers within it, which load custom apps.
>>>> 
>>>> We use the Digester in the server itself, and some of the 
>>>> apps being loaded
>>>> in the containers also want to use the Digester. The problem 
>>>> is that when an
>>>> app creates a Digester instance, it is created by the parent (system)
>>>> classloader that loaded the server, since the server had 
>>>> already used the
>>>> Digester and that classloader knows about it. When the 
>>>> Digester then does a
>>>> Class.forName in one of its rules to create an object, it 
>>>> knows nothing
>>>> about the container's ClassLoader and the classes within it. 
>>>> The class is
>>>> only withing the app, and so can't be found.
>>>> 
>>>> Is there any downside to changing the Digester to always use:
>>>>   Thread.getCurrentThread.getContextClassLoader.loadClass(name);
>>>> instead of 
>>>>   class.forName(name);
>>>> 
>>>> The code would no longer work in JDK 1.1, but that is already 
>>>> the case...
>>>> 
>>> 
>> 
>> 



Re: Bad classloading in Digester

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Tue, 1 May 2001, Scott Sanders wrote:

> I can apply the patch to the code in jakarta-commons-sandbox as well.
> 
> I would assume that a dependency on JDK 1.2 is not a problem.  Someone 
> will speak up if it is not.
> 

No, it's not a problem.  Struts requires 1.2 or later.

> Scott
> 

Cragi


> Colin Sampaleanu wrote:
> 
> > There was never any reply to this message (below) I sent a few months ago
> > about a problem with the method used by the Digestor for class loading.
> > 
> > In a number of places, it uses the old style
> > 	class.forName(name);
> > instead of the proper
> > 	Thread.getCurrentThread.getContextClassLoader.loadClass(name);
> > 
> > The second form is _much_ preferred to the first, because the first will
> > potentially fail in any situation where there are multiple classloaders (one
> > owning the other), and the Digester is used in code loaded by both
> > classloaders (please see my original message for more details).
> > 
> > This kind of situation is very common any time you have something like a
> > server (web, etc.) with containers in it, each container having its own
> > classloader associated with it in order to handle code visibility and
> > versioning. Using the digester in this situation is not possible without
> > modifying the code to use the second form.
> > 
> > I am quite willing and able to upload patches to 4 digester files to fix
> > this, assuming they will be checked in by somebody. The only implication is
> > that the code will no longer run under JDK 1.1, but Struts already needs 1.2
> > in any case...
> > 
> > For more details on classloading issues in Java, here are a couple of
> > excellent white papers:
> > Understanclind Class.forName();
> > http://www.develop.com/downloads/DynLoad.zip
> > Exploiting the Java Virtual Machine:
> > http://www.develop.com/downloads/DevWPJav.pdf
> > 
> > 
> > 
> > 
> >> -----Original Message-----
> >> From: Colin Sampaleanu [mailto:colin@bspark.com]
> >> Sent: February 22, 2001 10:06 PM
> >> To: 'struts-dev@jakarta.apache.org'
> >> Subject: ClassLoader used in Digester
> >> 
> >> 
> >> We are currently using the digester in a server we build that 
> >> uses custom
> >> classloaders for some containers within it, which load custom apps.
> >> 
> >> We use the Digester in the server itself, and some of the 
> >> apps being loaded
> >> in the containers also want to use the Digester. The problem 
> >> is that when an
> >> app creates a Digester instance, it is created by the parent (system)
> >> classloader that loaded the server, since the server had 
> >> already used the
> >> Digester and that classloader knows about it. When the 
> >> Digester then does a
> >> Class.forName in one of its rules to create an object, it 
> >> knows nothing
> >> about the container's ClassLoader and the classes within it. 
> >> The class is
> >> only withing the app, and so can't be found.
> >> 
> >> Is there any downside to changing the Digester to always use:
> >>   Thread.getCurrentThread.getContextClassLoader.loadClass(name);
> >> instead of 
> >>   class.forName(name);
> >> 
> >> The code would no longer work in JDK 1.1, but that is already 
> >> the case...
> >> 
> 
> 
> 


Re: Bad classloading in Digester

Posted by Scott Sanders <sa...@totalsync.com>.
I can apply the patch to the code in jakarta-commons-sandbox as well.

I would assume that a dependency on JDK 1.2 is not a problem.  Someone 
will speak up if it is not.

Scott

Colin Sampaleanu wrote:

> There was never any reply to this message (below) I sent a few months ago
> about a problem with the method used by the Digestor for class loading.
> 
> In a number of places, it uses the old style
> 	class.forName(name);
> instead of the proper
> 	Thread.getCurrentThread.getContextClassLoader.loadClass(name);
> 
> The second form is _much_ preferred to the first, because the first will
> potentially fail in any situation where there are multiple classloaders (one
> owning the other), and the Digester is used in code loaded by both
> classloaders (please see my original message for more details).
> 
> This kind of situation is very common any time you have something like a
> server (web, etc.) with containers in it, each container having its own
> classloader associated with it in order to handle code visibility and
> versioning. Using the digester in this situation is not possible without
> modifying the code to use the second form.
> 
> I am quite willing and able to upload patches to 4 digester files to fix
> this, assuming they will be checked in by somebody. The only implication is
> that the code will no longer run under JDK 1.1, but Struts already needs 1.2
> in any case...
> 
> For more details on classloading issues in Java, here are a couple of
> excellent white papers:
> Understanclind Class.forName();
> http://www.develop.com/downloads/DynLoad.zip
> Exploiting the Java Virtual Machine:
> http://www.develop.com/downloads/DevWPJav.pdf
> 
> 
> 
> 
>> -----Original Message-----
>> From: Colin Sampaleanu [mailto:colin@bspark.com]
>> Sent: February 22, 2001 10:06 PM
>> To: 'struts-dev@jakarta.apache.org'
>> Subject: ClassLoader used in Digester
>> 
>> 
>> We are currently using the digester in a server we build that 
>> uses custom
>> classloaders for some containers within it, which load custom apps.
>> 
>> We use the Digester in the server itself, and some of the 
>> apps being loaded
>> in the containers also want to use the Digester. The problem 
>> is that when an
>> app creates a Digester instance, it is created by the parent (system)
>> classloader that loaded the server, since the server had 
>> already used the
>> Digester and that classloader knows about it. When the 
>> Digester then does a
>> Class.forName in one of its rules to create an object, it 
>> knows nothing
>> about the container's ClassLoader and the classes within it. 
>> The class is
>> only withing the app, and so can't be found.
>> 
>> Is there any downside to changing the Digester to always use:
>>   Thread.getCurrentThread.getContextClassLoader.loadClass(name);
>> instead of 
>>   class.forName(name);
>> 
>> The code would no longer work in JDK 1.1, but that is already 
>> the case...
>>