Björn Kautler created XERCESJ-1772:
--------------------------------------

             Summary: {{ClassCastException}} in {{SAXParser}} constructor if 
Xerces comes from different thread-context class loaders
                 Key: XERCESJ-1772
                 URL: https://issues.apache.org/jira/browse/XERCESJ-1772
             Project: Xerces2-J
          Issue Type: Bug
    Affects Versions: 2.12.2
            Reporter: Björn Kautler


MCVE is following, but the full story is like this:
 - Gradle has Ant integrated on its class loader.
 - Ant in its {{org.apache.tools.ant.util.JAXPUtils.getNSParserFactory}} uses 
{{javax.xml.parsers.SAXParserFactory.newInstance}} to create a 
{{SAXParserFactory}} and remembers it for future usage
 - {{javax.xml.parsers.FactoryFinder.getProviderClass}} uses the TCCL 
(thread-context class loader) to find the {{SAXParserFactory}} to be used
 - Now the {{SAXParserFactory}} that {{JAXPUtils}} remembers is the Xerces one 
from that TCCL that is coming from the build script class path
 - If that {{SAXParserFactory}} now is asked to create a 
{{{}newSAXParser(){}}}, it ultimately calls the 
{{org.apache.xerces.parsers.SAXParser}} constructor from that same class loader 
the factory is coming from
 - This constructor uses 
{{org.apache.xerces.parsers.ObjectFactory.createObject}} to create a new 
{{XMLParserConfiguration}}
 - This method again searches on the current TCCL for the class
 - After an instance was created, it tries to cast it to 
{{XMLParserConfiguration}} from the same class loader as the factory

If it now happens, that the TCCL changed, for example because you run a Gradle 
build with a different buildscript classpath and thus a different class loader 
containing Xerces you get a {{ClassCastException}} like:
{code:java}
class org.apache.xerces.parsers.XIncludeAwareParserConfiguration cannot be cast 
to class org.apache.xerces.xni.parser.XMLParserConfiguration 
(org.apache.xerces.parsers.XIncludeAwareParserConfiguration is in unnamed 
module of loader java.net.URLClassLoader @2280cdac; 
org.apache.xerces.xni.parser.XMLParserConfiguration is in unnamed module of 
loader java.net.URLClassLoader @681a9515)
{code}
 

Condensed, you can reproduce this issue with the following lines of code with 
Xerces *not* being on the application classpath:
{code:java}
URL[] xercesUrl = {new File("path/to/xercesImpl-2.12.2.jar").toURI().toURL()};

Thread.currentThread().setContextClassLoader(new URLClassLoader(xercesUrl));

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.newSAXParser();

Thread.currentThread().setContextClassLoader(new URLClassLoader(xercesUrl));

factory.newSAXParser();{code}
This results in said {{{}ClassCastException{}}}:
{code:java}
Exception in thread "main" java.lang.ClassCastException: class 
org.apache.xerces.parsers.XIncludeAwareParserConfiguration cannot be cast to 
class org.apache.xerces.xni.parser.XMLParserConfiguration 
(org.apache.xerces.parsers.XIncludeAwareParserConfiguration is in unnamed 
module of loader java.net.URLClassLoader @2280cdac; 
org.apache.xerces.xni.parser.XMLParserConfiguration is in unnamed module of 
loader java.net.URLClassLoader @681a9515)
    at org.apache.xerces.parsers.SAXParser.<init>(Unknown Source)
    at org.apache.xerces.parsers.SAXParser.<init>(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.<init>(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl.<init>(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParser(Unknown Source)
    at foo.Foo.main(Foo.java:21)
{code}
 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to