这是一个更为一般性的问题: 我正在使用xstream和woodstox,woodstox附带了一个服务提供者,用于注册com.ctc.wstx.stax.WstxOutputFactory的woodstox jar中的javax.xml.stream.XMLOutputFactory。 我想提供自己的javax.xml.stream.XMLOutputFactory,并且在类路径中仍然有woodstox jar。我知道我可以提供我自己的系统属性javax.xml.stream.XMLOutputFactory,但我正试图从我们的开发团队中解脱麻烦,并在我的jar中使用服务文件或者在我的战争中使用META -INF / services文件夹。查看javax.xml.stream.FactoryFinder的代码如何确保我的代码 META-INF / services / javax.xml.stream.XMLOutputFactory文件将是FactoryFinder使用的文件吗?
我们将xstream与camel一起使用,无法找到将工厂注入XStreamDataFormat的方法
答案 0 :(得分:8)
首先:我强烈建议您不要依赖JDK SPI接口,而应该简化生活,不要使用它。它实际上没有增加自己注入XMLInputFactory
和/或XMLOutputFactory
的价值。对于注射,你可以使用Guice(或Spring);或者只是手动传递它。由于这些工厂没有自己的依赖关系,这很容易。
但是如果选择(或必须)使用XMLInputFactory.newInstance()
,您可以为“javax.xml.stream.XMLOutputFactory”和“javax.xml.stream.XMLInputFactory”定义一个System属性。
那为什么不使用JDK方法呢?原因有多:
不幸的是,Oracle似乎仍然坚持要添加这种已知错误的方法来注册服务提供商。为什么?可能是因为他们没有他们自己的DI lib /框架(Guice是谷歌,Spring by Springsource),他们往往非常控制饥饿。
答案 1 :(得分:6)
你可以这样做来指定你想要使用的XMLOutputFactory实现:
System.setProperty("javax.xml.stream.XMLOutputFactory", ... full classname You want to use ...);
来源: http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/SJSXP4.html
从JAXP派生XMLInputFactory.newInstance()方法 确定要加载的特定XMLInputFactory实现类 通过使用以下查找过程:
- 使用javax.xml.stream.XMLInputFactory系统属性。
- 使用JRE目录中的lib / xml.stream.properties文件。
- 使用Services API(如果可用)通过查看META-INF / services / javax.xml.stream.XMLInputFactory来确定类名 JRE中可用的罐子中的文件。
- 使用平台默认的XMLInputFactory实例。
醇>
答案 2 :(得分:5)
我发现如果我把服务文件放在 WEB-INF / classes / services / javax.xml.stream.XMLOutputFactory然后它将首先在classpath中和WEB-INF / lib中的jars之前。 那是我的解决方案。
答案 3 :(得分:3)
我们遇到过类似的问题,解析会在本地运行但在服务器上失败。调试后发现服务器正在使用阅读器com.ctc.wstx.evt.WstxEventReader
而本地读者是com.sun.xml.internal.stream.XMLEventReaderImpl
我们设置以下属性来解决它。
System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl");
答案 4 :(得分:0)
如果您的实现位于jar中,那么请确保它位于类路径上的woodstox.jar之前,然后FactoryFinder将使用您的实现。