Play Framework:PDF 0.9模块与JavaAPIforKml不兼容

时间:2012-02-24 06:49:11

标签: java playframework pdf-generation kml

我的Play项目目前依赖于Play的pdf module version 0.9JavaAPIforKml 2.2.0(用于创建代表kml文件的对象)。

之前我使用的是pdf module version 0.7,一切正常。

现在我已升级到0.9版,我对基于kml的类的所有测试现在都失败了。我得到的例外是:

java.lang.ClassNotFoundException: org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl
at java.lang.ClassLoader.findClass(ClassLoader.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at     
play.classloading.ApplicationClassloader.loadClass(ApplicationClassloader.java:93)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at javax.xml.datatype.FactoryFinder.getProviderClass(FactoryFinder.java:115)
at javax.xml.datatype.FactoryFinder.newInstance(FactoryFinder.java:146)
at javax.xml.datatype.FactoryFinder.findJarServiceProvider(FactoryFinder.java:298)
at javax.xml.datatype.FactoryFinder.find(FactoryFinder.java:223)
at javax.xml.datatype.DatatypeFactory.newInstance(DatatypeFactory.java:131)
at com.sun.xml.bind.DatatypeConverterImpl.<clinit>(DatatypeConverterImpl.java:833)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$3.run(JAXBContextImpl.java:287)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$3.run(JAXBContextImpl.java:286)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:285)
at 
com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at de.micromata.opengis.kml.v_2_2_0.Kml.getJaxbContext(Kml.java:631)
at de.micromata.opengis.kml.v_2_2_0.Kml.createMarshaller(Kml.java:640)
at de.micromata.opengis.kml.v_2_2_0.Kml.marshal(Kml.java:682)

导致异常的代码部分是:

de.micromata.opengis.kml.v_2_2_0.Kml kml = ...
kml.marshal(someByteArrayOutputStream); // This is the line that causes the exception

如果我切换回pdf模块版本0.7,一切都会再次运行。有谁知道我可以做些什么来继续使用pdf模块0.9版并让kml测试继续工作?

如果有帮助,pdf模块版本0.9具有以下依赖性:

core-renderer.jar
itest-2.1.7.jar
jaxen-1.1.jar
jtidy-r938.jar
shani-parser-v1.4.17.jar
xml-apis.jar
yahp-internal.jar
yahp.jar

虽然JavaApiForKml版本2.2.0具有以下依赖性:

jaxb-impl 2.2
jaxb-xjc 2.2
xmlunit 1.2

3 个答案:

答案 0 :(得分:1)

我也在玩Play! PDF模块打破了我(以前工作)的XML解析。

感谢您分享您的解决方案,它帮助了很多!虽然有一种更优雅的方式来实现它。

由于xerces生活在maven central上,你应该能够将它添加到你的dependencies.yml:

- xerces -> xercesImpl 2.10.0

这样您就不需要为它创建模块,也不用担心在同步时会被覆盖。

(我使用的是2.10.0,但您可以将其更换为最合适的版本)

干杯

答案 1 :(得分:1)

出现此问题是因为PDF模块使用jar文件xml-apis.jarorg.allcolor.xml.parser.CDocumentBuilderFactory添加到可用的DocumentBuilderFactory中。不幸的是,这个文档构建器似乎没有很好地处理一些功能,如XPath评估。

当我们将Xerces库添加到项目中时,它的DocumentBuilder取代了前一个,一切正常。但这是偶然的:恰好Xerces DocumentBuilderFactory是第一个被发现的。

为了强制应用程序使用默认的DocumentBuilderFactory实现,我认为最好定义相应的系统属性,如javadoc中所定义。

-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl

或者,我们可以创建一个新的DocumentBuilderFactory实例,明确指出应该使用哪个实现:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", null);

答案 2 :(得分:0)

我已经设法让我的构建再次工作,但我并不特别喜欢这个解决方案。首先,我从apache下载xerces2库。

我将jar放入lib目录并且构建工作正常。这个库以前从未存在过,所以我不确定它之前是如何工作的。

然后我将xerces jar放在它自己的游戏“模块”中,称为xerces,这样当运行play deps --sync时,xerces jar就不会从lib目录中擦除。使用此技术运行构建后,构建再次失败!

因此,经过更多的游戏,我认为它可能与罐子的排序有关。我将我创建的xerces模块重命名为apache-xerces并重新运行构建,然后构建再次开始工作!