Bug 21488 - Infocenter ClassCastException in Xerces
Summary: Infocenter ClassCastException in Xerces
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: User Assistance (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows 2000
: P2 major (vote)
Target Milestone: 2.0.1   Edit
Assignee: Konrad Kolosowski CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 21419
  Show dependency tree
 
Reported: 2002-07-11 11:08 EDT by Konrad Kolosowski CLA
Modified: 2002-08-07 09:52 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Konrad Kolosowski CLA 2002-07-11 11:08:25 EDT
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.
Comment 1 Konrad Kolosowski CLA 2002-07-14 01:53:18 EDT
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.
Comment 2 Konrad Kolosowski CLA 2002-07-15 12:09:01 EDT
Released a fix to use web application 
class loader as a parent for Eclipse boot class loader.