You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by toby cabot <to...@caboteria.org> on 2005/01/24 22:56:35 UTC

problem with xerces and web apps

Hi Folks,

I've been using Geronimo for a while now and it works great.  I just
updated from Subversion today and now I have a problem at run-time
with Xerces inside a web app that appears to be classloader related.
I'm using Axis which uses Xerces so I added the xerces jars to my .war
file.  When Xerces starts I get:

java.lang.ClassCastException
        at org.apache.xerces.parsers.DOMParser.<init>(DOMParser.java:138)
        at org.apache.xerces.parsers.DOMParser.<init>(DOMParser.java:108)
        at org.apache.xerces.jaxp.DocumentBuilderImpl.<init>(DocumentBuilderImpl.java:52)
        at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(DocumentBuilderFactoryImpl.java:47)
        at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:291)
        at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:308)
        at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:176)
        at org.apache.axis.AxisEngine.init(AxisEngine.java:162)
        at org.apache.axis.AxisEngine.<init>(AxisEngine.java:146)
        at org.apache.axis.server.AxisServer.<init>(AxisServer.java:87)
        at org.apache.axis.server.DefaultAxisServerFactory.createServer(DefaultAxisServerFactory.java:109)
        at org.apache.axis.server.DefaultAxisServerFactory.getServer(DefaultAxisServerFactory.java:73)
        at org.apache.axis.server.AxisServer.getServer(AxisServer.java:72)
        at org.apache.axis.transport.http.AxisServletBase.getEngine(AxisServletBase.java:183)
        at org.apache.axis.transport.http.AxisServletBase.getOption(AxisServletBase.java:370)
        at org.apache.axis.transport.http.AxisServletBase.init(AxisServletBase.java:110)
        at javax.servlet.GenericServlet.init(GenericServlet.java:168)

The Xerces code looks like (see [1]):

        super((XMLParserConfiguration)ObjectFactory.createObject(
            "org.apache.xerces.xni.parser.XMLParserConfiguration",
            "org.apache.xerces.parsers.XML11Configuration"
            ));

So it looks as if the problem is that the object that comes back from
ObjectFactory.createObject() can't be cast to an
XMLParserConfiguration.  The strange part is that it looks as if the
correct object is coming back, at least if I just print out the class
name.  The difference between a 2 week old Geronimo build and this one
is that this one appears to have two different instances of
org.apache.geronimo.jetty.JettyClassLoader in play, whereas the 2 week
old version only had one.  Xerces ObjectFactory has explicit code to
find the right classloader to use, their code is in findClassLoader()
at [2], in the two week old Geronimo build that code returned the same
classloader that this.getClass().getClassLoader() returns and the cast
succeeds, in the current build it finds a different classloader and
the cast throws a ClassCastException.

Any ideas how I can get around this are appreciated.

Thanks,
Toby

[1] DOMParser.java: http://cvs.apache.org/viewcvs.cgi/xml-xerces/java/src/org/apache/xerces/parsers/DOMParser.java?rev=1.72&view=auto
[2] Code that Xerces uses to find the classloader: 
http://cvs.apache.org/viewcvs.cgi/xml-xerces/java/src/org/apache/xerces/parsers/ObjectFactory.java?rev=1.9&view=auto

Re: problem with axis/xerces and web apps

Posted by toby cabot <to...@caboteria.org>.
Thanks for your help, David.  I got things working, but it took a fair
bit of messing around.  It seems that Axis really likes to be loaded
by the same classloader as the code that it's working with.  For
example, when I used the Axis that's built into Geronimo I got

Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at org.apache.axis.utils.BeanPropertyDescriptor.set(BeanPropertyDescriptor.java:117)

... when Axis tried to load one of my classes (which are in the war
file).  This looks like a similar problem to the Xerces problem that
started this thread (i.e. can't load a class using the context
classloader and then cast it).  So in the end I've got Axis and Castor
in the war file, and context-priority-classloader=true and that works
for me.  I'm using Geronimo's commons-logging and commons-discovery,
however.

Can I ask about something?  It seems from the comments on
http://wiki.apache.org/geronimo/Deployment#head-754164850f38c1ecdaf6b8ed894cb192bc36c5f4-2
and the default "false" value of context-priority-classloader that
Geronimo's preferred configuration is to load classes from the
container-wide classloader first, then the war file classloader.  In
the Servlet spec it's "recommended" that classes be loaded from the
war first.  Is this a case where you guys think that the spec is
off-base or just an oversight?  It doesn't really matter since it's a
recommendation rather than a requirement, but it would be cool if
Geronimo's default could follow the spec's recommendation.

Again, thanks for your help on this,
Toby

Re: problem with axis/xerces and web apps

Posted by David Jencks <da...@yahoo.com>.
On Jan 27, 2005, at 2:34 PM, toby cabot wrote:

> Thanks David.
>
> On Thu, Jan 27, 2005 at 10:38:27AM -0800, David Jencks wrote:
>> Are you using a geronimo plan with
>> <context-priority-classloader>true</context-priority-classloader>
>> for your web app?
>
> I wasusing a value of "false" before, but I tried "true" and as you
> expected it caused other problems, specifically:
>
> org.apache.commons.discovery.DiscoveryException: Class  
> org.apache.geronimo.kernel.log.GeronimoLogFactory does not implement  
> org.apache.commons.logging.LogFactory
>         at  
> org.apache.commons.discovery.tools.ClassUtils.verifyAncestory(ClassUtil 
> s.java:134)
>         at  
> org.apache.commons.discovery.tools.SPInterface.verifyAncestory(SPInterf 
> ace.java:155)
>         at  
> org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface. 
> java:149)
>         at  
> org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverCl 
> ass.java:533)
>         at  
> org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingl 
> eton.java:372)
>         at  
> org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingl 
> eton.java:332)
>         at  
> org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at  
> org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.j 
> ava:41)
>         at  
> org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java: 
> 33)
>
>> I think it's likely that we added axis to geronimo between early jan
>> and now.
>>
>> If this doesn't work (I think there is a reasonable chance it will
>> cause other problems) you might need to assemble geronimo using the
>> versions of axis and xerces you need.
>>
>> What happens if you use the versions of axis and xerces that geronimo
>> uses? Are our versions out of date?  If we actually implemented j2ee
>> web services would that also solve the problem :-)?
>
> I don't think it's a version problem, the versions of the tools that
> you guys are using seem to be up-to-date.  If I include Xerces in my
> war file then Axis appears to load that one, but it crashes with the
> ClassCastException in my previous email, seemingly because of some
> code in Xerces that loads a class with one classloader and tries to
> cast it to the same class, only loaded by a different classloader.  If
> I *don't* include Xerces in my war file then Castor (which I'm also
> using) can't find some xerces class that it needs so it throws.  Don't
> remember the stack trace but I can reproduce it if it helps.
>
> How hard do you think it would be to build Geronimo without Axis?  If
> Geronimo pulls the classes from the jars in my war file then it should
> work fine, at least it used to work fine.  Alternatively, could
> Geronimo load classes from the war file lib directory in preference to
> the repository?

It would probably be easier to put castor in the geronimo repo and add  
a dependency to it in j2ee-server-plan.xml than to remove axis from  
geronimo.

However, if you want to remove axis, what you need to do is:

look in all the assembly plans and remove all the axis jars, the  
geronimo-axis and the geronimo-axis-builder jars from the dependencies.  
  (geronimo-axis has transitive dependencies to most/all the plain axis  
jars, so the geronimo-axis* jars should be the only ones you'll find).   
You also have to remove the axis-builder gbean.

I'm not entirely sure if you can just remove references to the  
axis-builder gbean from the module builders or if you have to write a  
do-nothing gbean that implements and exposes ServiceReferenceBuilder,  
and deploy a copy of it in place of the axis-builder gbean.  (if you  
give it the same name and the gbeaninfo the same type "ModuleBuilder"  
you won't have to track down the references)

If I was doing this I would be sure to get at least one gbean name  
wrong so the deployers wouldn't start :-)   So, check the console  
output for non-started gbeans and the log also.

thanks
david jencks

>
> Thanks for your help,
> Toby
>


Re: problem with axis/xerces and web apps

Posted by toby cabot <to...@caboteria.org>.
Thanks David.

On Thu, Jan 27, 2005 at 10:38:27AM -0800, David Jencks wrote:
> Are you using a geronimo plan with
> <context-priority-classloader>true</context-priority-classloader>
> for your web app?

I wasusing a value of "false" before, but I tried "true" and as you
expected it caused other problems, specifically:

org.apache.commons.discovery.DiscoveryException: Class org.apache.geronimo.kernel.log.GeronimoLogFactory does not implement org.apache.commons.logging.LogFactory
        at org.apache.commons.discovery.tools.ClassUtils.verifyAncestory(ClassUtils.java:134)
        at org.apache.commons.discovery.tools.SPInterface.verifyAncestory(SPInterface.java:155)
        at org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface.java:149)
        at org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:533)
        at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:372)
        at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:332)
        at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
        at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)

> I think it's likely that we added axis to geronimo between early jan 
> and now.
> 
> If this doesn't work (I think there is a reasonable chance it will 
> cause other problems) you might need to assemble geronimo using the 
> versions of axis and xerces you need.
> 
> What happens if you use the versions of axis and xerces that geronimo 
> uses? Are our versions out of date?  If we actually implemented j2ee 
> web services would that also solve the problem :-)?

I don't think it's a version problem, the versions of the tools that
you guys are using seem to be up-to-date.  If I include Xerces in my
war file then Axis appears to load that one, but it crashes with the
ClassCastException in my previous email, seemingly because of some
code in Xerces that loads a class with one classloader and tries to
cast it to the same class, only loaded by a different classloader.  If
I *don't* include Xerces in my war file then Castor (which I'm also
using) can't find some xerces class that it needs so it throws.  Don't
remember the stack trace but I can reproduce it if it helps.
 
How hard do you think it would be to build Geronimo without Axis?  If
Geronimo pulls the classes from the jars in my war file then it should
work fine, at least it used to work fine.  Alternatively, could
Geronimo load classes from the war file lib directory in preference to
the repository?

Thanks for your help,
Toby

Re: problem with axis/xerces and web apps

Posted by David Jencks <da...@yahoo.com>.
Are you using a geronimo plan with

              
<context-priority-classloader>true</context-priority-classloader>

for your web app?

I think it's likely that we added axis to geronimo between early jan 
and now.

If this doesn't work (I think there is a reasonable chance it will 
cause other problems) you might need to assemble geronimo using the 
versions of axis and xerces you need.

What happens if you use the versions of axis and xerces that geronimo 
uses? Are our versions out of date?  If we actually implemented j2ee 
web services would that also solve the problem :-)?

thanks
david jencks

On Jan 27, 2005, at 7:51 AM, toby cabot wrote:

> On Mon, Jan 24, 2005 at 04:56:35PM -0500, toby cabot wrote:
>> I have a problem at run-time
>> with Xerces inside a web app that appears to be classloader related.
>> I'm using Axis which uses Xerces so I added the xerces jars to my .war
>> file.  When Xerces starts I get:
>>
>> java.lang.ClassCastException
>
> I'm still not certain what's going on, but I have some clues.  The
> "old" version of Geronimo (i.e. early January) loads Axis from the
> jars in my .war file, but the new version loads Axis from the jars in
> the geronimo repository.  This seems to cause a problem when Axis then
> loads Xerces from the jars in my war file.
>
> Is there a way that I can get the old behavior, i.e. have Geronimo use
> the version of Axis that's packaged in my war file?
>
> Thanks,
> Toby
>


Re: problem with axis/xerces and web apps

Posted by toby cabot <to...@caboteria.org>.
On Mon, Jan 24, 2005 at 04:56:35PM -0500, toby cabot wrote:
> I have a problem at run-time
> with Xerces inside a web app that appears to be classloader related.
> I'm using Axis which uses Xerces so I added the xerces jars to my .war
> file.  When Xerces starts I get:
> 
> java.lang.ClassCastException

I'm still not certain what's going on, but I have some clues.  The
"old" version of Geronimo (i.e. early January) loads Axis from the
jars in my .war file, but the new version loads Axis from the jars in
the geronimo repository.  This seems to cause a problem when Axis then
loads Xerces from the jars in my war file.

Is there a way that I can get the old behavior, i.e. have Geronimo use
the version of Axis that's packaged in my war file?

Thanks,
Toby