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]