问题
This problem ties in with the many discussions about the Xerces dependency hell, but I can't seem to solve it.
I'm trying to export LaTeX code to PDF in Java. My code is part of an OSGI bundle for Cytoscape 3.4 and is managed and built with Maven.
The LaTeX library is jlatexmath
(1.0.6) and to write to SVG and PDF I want to try the apache fop
(0.95) libs.
Fop is depending on a whole range of batik
libraries, which in turn depend on xml-apis
(1.3.04).
With xml-apis
included, I get this error:
java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to javax.xml.parsers.DocumentBuilderFactory
at javax.xml.parsers.DocumentBuilderFactory.newInstance(Unknown Source)
at org.scilab.forge.jlatexmath.TeXFormulaSettingsParser.<init>(TeXFormulaSettingsParser.java:74)
Which is understandable as the implementation of DocumentBuilderFactory
is supposed to be com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
as included in the JRE.
When I exclude the xml-apis and xml-apis-ext libs, I get another error:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>0.95</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis-ext</artifactId>
</exclusion>
</exclusions>
</dependency>
java.lang.ClassNotFoundException: org.w3c.dom.Document not found by... [115]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Which is weird, as org.w3c.dom.Document
should also just be in the JRE.
So, how can I force Java to use the classes included in Java instead of looking for the ones loaded from the Maven dependencies?
回答1:
Your bundle needs to import the package org.w3c.dom
. You must import all packages that your bundle depends on, with the solitary exception of packages starting with java.
, e.g. java.lang
, java.net
etc.
回答2:
I managed to fix it, thanks to the suggestion of Neil Bartlett that org.w3c.dom
wasn't imported (although I'm still not sure why an "import *" didn't suffice).
In the configuration instructions of the maven-bundle-plugin, I changed the import to:
<Import-Package>org.w3c.dom,*;resolution:=optional</Import-Package>
Also, xml-apis-ext
should not be excluded, so the fop
dependency became:
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>0.95</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
Then, to be complete, the fop artifact seemed to be needing a class from the avalon-framework-impl
, which was nowhere in the maven dependencies, so I added it separately, while excluding all new attempts to include xml-apis
:
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework-impl</artifactId>
<version>4.3</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xmlParserAPIs</artifactId>
</exclusion>
</exclusions>
</dependency>
来源:https://stackoverflow.com/questions/45638091/classcastexception-org-apache-xerces-jaxp-documentbuilderfactoryimpl-cannot-be