dev@glassfish.java.net

Re: apache commons-* classes in AS

From: Jan Luehe <Jan.Luehe_at_Sun.COM>
Date: Mon, 17 Oct 2005 18:49:08 -0700

Hi Siva,

Sivakumar Thyagarajan wrote On 10/14/05 11:57,:
> Hi Abhijit
>
> Today I had a discussion with Binod and Harsha regarding this, and here
> are our thoughts.
>
> Do AS implementation classes have direct references to apache-common-*
> classes? If yes :

Yes, some of the classes in appserv-webtier import
org.apache.commons.modeler.*, org.apache.commons.logging.*,
org.apache.commons.beanutils.*, etc.

> The original proposed classloader onepager's design would accomodate
> this fine and we could move apache-commons-* jars to the AS chain.
> However now since appserv-rt and all AS implementation classes are at
> the shared chain level, we would need to promote apache-common-* classes
> as well to the shared chain, thus making overriding of these jars in the
> application level not possible

Unfortunately, I don't think this would help us solve 6314912 ("Parsing
Error: Tiles not working in SJSAS 8.1"), which is also a problem in 9.0.

6314912 is about the Digester in commons-digester being unable
to load any classes from a webapp's WEB-INF/classes or
WEB-INF/lib/[*.jar|*.zip].

The root cause of the problem is a regression in commons-digester,
which no longer has the Digester use the context classloader (which
corresponds to the webapp classloader in a J2EE environment) by
default.
Instead, Digester now uses its own classloader (obtained via
digester.getClass().getClassLoader()) by default to load any classes,
unless its "useContextClassLoader" property was set to TRUE.

This regression, which was introduced between commons-digester versions
1.0 and 1.1, does not cause any problems if a webapp bundles its own
commons-digester, and there is no commons-digester further up in the
classloader delegation chain: in this case,
digester.getClass().getClassLoader() will return the webapp classloader,
giving digester access to all of the webapp's own classes.

However, if there is a commons-digester higher up in the delegation
chain (as is the case with the AS), the webapp classloader will
delegate to it by default, giving it preference over the locally bundled
commons-digester and causing the problem described in 6314912.
In order for things to work again, one must add this configuration to
the webapp's sun-web.xml:

  <sun-web-app>
    <class-loader delegate="false"/>
  </sun-web-app>

which will cause the local commons-digester to be given preference
over the commons-digester higher up in the chain.

I think our goal should be for a webapp to be able to bundle and use
its own commons-digester without having to set its delegate flag to
FALSE. This will be possible only if the commons-digester used by AS
impl classes was completely "hidden" from all webapps.

This is just one example of why not letting a webapp override
a "commons" class may cause classloading issues.

Let me know what you think.

Thanks,


Jan