Page: http://wiki.cocoondev.org/Wiki.jsp?page=SandBox , version: 114 on Tue Jun 3 21:23:07 2003 by 151.42.205.26
+ + ;term:ex + Page: http://wiki.cocoondev.org/Wiki.jsp?page=ThemedSite , version: 6 on Tue Jun 3 21:47:21 2003 by AndreasHartmann Page: http://wiki.cocoondev.org/Wiki.jsp?page=People , version: 138 on Tue Jun 3 21:17:25 2003 by 217.162.169.115 + * [AndreasHartmann] -- Lenya committer and cocooncenter webmaster Page: http://wiki.cocoondev.org/Wiki.jsp?page=EndorsedLibsProblem , version: 4 on Tue Jun 3 21:13:57 2003 by SylvainWallez - Here's a note from [SylvainWallez] on [cocoon-dev|http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105464704814494&w=2]. I'm copying it here as this is important information. + !!''Why Xalan fails with JDK 1.4, and the solutions'' + !! The problem + The JDK 1.4 introduced the new XML-related {{java.xml.*}} APIs, and is shipped with an XML parser (Crimson and now Xerces) and an XSLT Processor (Xalan). Although this helped making XML technologies more widespread and easy to use, this led to numerous problems in Cocoon. - Note that this is only valid if the version of Cocoon that you're using is built from the CVS of June 3rd, 2003. - ---- - Hi all, + Why are there some problems ? Well, the version of Xalan shipped with the JDK is old (and gets older as time goes by), and Cocoon requires more recent versions (bug fixes, enhancements, XSLTC, etc). And there are some conflicts between these versions. - Short story: once again, I've hit the famous endorsed library problem. - So as usual I copied Cocoon's Xalan and Xerces to - tomcat/common/endorsed, but unfortunately this broke another application - that was running in the same Tomcat. + The Servlet specification (section 9.7.2) states that webapp classes, located in {{WEB-INF/lib}} and {{WEB-INF/classes}}, should be loaded preferably to the same classes in the container-wide libraries. But it also states that a webapp should not override J2SE classes, of which the XML apis and Xalan are not part of. - Damn. How to solve this ? Install another Tomcat ? Yeah, it will work, - but will add yet-another-JVM to the server, which I wanted to avoid. So, - I decided to use ParanoidCocoonServlet, and discovered that it was - actually not paranoid at all because it was not using the - ParanoidClassLoader it was supposed to use :-( + And this is what happens in Tomcat (see the excellent [classloader how-to|http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html]) : the "old" Xalan classes present in the JDK are loaded instead of the new ones shipped with Cocoon. - So I refactored a bit all our servlets and now ParanoidCocoonServlet is - __really__ paranoid. This means, that its classloader will __always__ try to - load classes and resources first from WEB-INF/lib and WEB-INF/classes, - ignoring any similar classes existing in the parent classloader. Xalan, - Xerces, etc are now really immune to whatever version of the same - library can exist either in the JDK or in the servlet engine. + So you think Cocoon then runs with the old Xalan ? This is unfortunately not so simple : Tomcat (at least some versions of it) doesn't use the same priority algorithm for classes and resources. And Xalan has a lot of configurations written in resources included in its jar file. So it happens that classes from the JDK's "old" Xalan load a resource, which is fetched from the "new" jar, and this resource lists class names that do not exist in the JDK's old Xalan. - Such a strong shielding can have some drawbacks, however : if a class is - given by the servlet engine (e.g. a JNDI context) and the same class - exists in the webapp libs (e.g. in jndi.jar), then you're very likely to - get a ClassCastException. This is likely to happen mostly with standard - APIs, and the solution is then to remove the offending library from your - WEB-INF/lib. - Enjoy,\\ - Sylvain + Result ? Bing, Bang, Crash ! You got a blank page and some cryptic error messages in the servlet engine's log file (and not always in Cocoon's logs) : + * {{java.lang.IllegalAccessError: class org.apache.xml.dtm.ref.sax2dtm.SAX2DTM2$AncestorIterator cannot access its superclass org.apache.xml.dtm.ref.DTMDefaultBaseIterators$InternalAxisIteratorBase}} + * {{The output format must have a '{http://xml.apache.org/xslt}content-handler' property!}} (see [my post|http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=104547205330116&w=2] about this) + + !! Fixing the problem with the "endorsed" directory + + Fortunately, the JDK [provides a mechanism|http://java.sun.com/j2se/1.4.1/docs/guide/standards/index.html] to solve this problem : libraries shipped with the JDK can be upgraded by putting the updated libraries either in the {{jre/lib/endorsed}} libraries, or in a path given using the {{java.endorsed.dirs}} JVM argument. + + So you can put new versions of Xalan and Xerces there. But changing the configuration of the JDK is not something that you may want to do when you deploy a web application. + + Fortunately (again), Tomcat startup scripts automatically sets {{java.endorsed.dirs}} to {{''tomcat-home''/common/endorsed}}. This means you just have to put the new jars here and not in the JDK. + + However (this story never ends), you may encounter the following problem : two different webapps running on the same Tomcat require each a different version of Xalan ! What's the solution, then ? Installing each application in a different Tomcat could be the solution, but requires yet another JVM to run on the server (not to mention the additional system maintainance for startup and shutdown). + + !! Fixing the problem with the ParanoidCocoonServlet + + [[This is valid if the Cocoon that you're using is built from the CVS of June 3rd, 2003 or later] + + Cocoon provides an alternate servlet named {{ParanoidCocoonServlet}}. What this servlet does is create a special classloader, and use it to load an run the standard {{CocoonServlet}}. + + This special classloader (the {{ParanoidClassLoader}}) has a stricter priority algorithm than the one defined by the servlet specification: classes and resources are __always__ searched first in {{WEB-INF/lib}} and {{WEB-INF/classes}}, ignoring any classes with the same name that exist in the parent classloader. Xalan, Xerces, etc. shipped with Cocoon are now really immune to whatever version of the same library can exist either in the JDK or in the servlet engine. + + This time, you no more have to copy your libraries somewhere outside your web application. + + Such a strong shielding can have some minor inconveniences, however : if a class is given by the servlet engine (e.g. a JNDI context) and the same class exists in the webapp libs (e.g. in {{WEB-INF/lib/jndi.jar}}), then you're very likely to get a {{ClassCastException}}. This is likely to happen mostly with standard APIs, and the solution is then to delete the offending library from your WEB-INF/lib. + + Why this exception ? Because a class is defined by its name ''and'' its classloader. This means that if you get an object from the servlet engine whose class is defined by the engine's classloader and try to cast it to a class with the same class name, but loaded by the {{ParanoidClassLoader}}, the cast will fail because the classes are different. + + + -- [SylvainWallez] + + ------ Page: http://wiki.cocoondev.org/Wiki.jsp?page=Main , version: 195 on Tue Jun 3 21:25:44 2003 by SylvainWallez + * June 3, 3003 + ** Added [EndorsedLibsProblem] - how to solve the Xalan problems with JDK 1.4 ''--[SylvainWallez]'' Page: http://wiki.cocoondev.org/Wiki.jsp?page=AndreasHartmann , version: 2 on Tue Jun 3 21:19:46 2003 by 217.162.169.115 - * ThemedSite + * [ThemedSite] ? + +
