Community
Participate
Working Groups
In the infocenter scenario under WebShpere, and Tomcat ClassCastExceptions are thrown from within Xerces code. This occurs in the post F1 drivers where xerces 4.0.3 was introduced. Old xerces jar works. java.lang.ClassCastException: org.apache.xerces.parsers.StandardParserConfiguration at org.apache.xerces.parsers.SAXParser.<init>(SAXParser.java:95) at org.eclipse.help.internal.toc.TocFileParser.parse(TocFileParser.java:71) or java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:135) at org.eclipse.help.internal.toc.TocFileParser.parse(TocFileParser.java:72) The errors are due to the fact that server has old xerces.jar on the classpath, and Eclipse has its own (newer Xerces) on the classpath of its class loader. The Xerces code however obtains class loader using Thread.getContextClassLoader (), the obtained parser implementation is not compatible with APIs that are available to Eclipse classloader. The exception is thrown. Xerces should use current class loader if creating parser (or parser factory) using context class loader fails. The exceptions are thrown in many places inside Eclipse, where XML parsers are created, and there is no simple work around for this problem.
When Eclipse is running on web server, more than one set of Xerces jars is available in VM. One set of Xerces jar exists in Eclipse Xerces plugin and should be used by code running inside Eclipse, another set is in the server or webapp lib directories. This is required by servlets and by the code internal to the server. The new Xerces contains pieces of code that can be written as: (SAXParserFactory)Thread.currentThread().getContextClassLoader().loadClass (className).newInstance() When executed inside Eclipse, running on the server, it causes the interface SAXParserFactory to be loaded from the Xerces jar in the Eclipse plugin. The class className is loaded from Xerces jar that is in the lib directory of the server, since usage of getContextClassLoader() causes ignoring of plugin class loaders and results in using class loader assigned to the application by a server. Since loading of a clas also causes loading of the super interfaces, two interfaces from different jars exists in a VM, and cast cannot be performed. If xerces did not call getContextClassLoader(), problem would not exists. I therefore belive Xerces code should ensure that current class loader will be used if the using class loader obtained from getContextClassLoader() fails. One way to work around Xerces problem could be to set Context class loader on every tread entering eclipse to the xerces plugin class loader, which is very messy and difficult to implement. Another short term workaround (until Xerces is fixed) is to use web application class loader as a parent for Eclipse boot class loader. This breaks isolation of Eclipse environment from the rest of the application and server. It results in Xerces jars from the server to always be used, even inside Eclipse. Since jars inside the Xerces plugin would never be used, the class cast exceptions are not thrown anymore.
Released a fix to use web application class loader as a parent for Eclipse boot class loader.