being 2008-05-16
今天用CXF写了个HelloWorld,放在glassfish上一运行,竟然出错!反编译CXF的代码跟踪了半天,原来是抽象类javax.xml.stream.XMLOutputFactory的实现冲突。该类在glassfish/lib/javaee.jar和CXF自带的包geronimo-stax-api_1.0_spec-1.0.1.jar中都有实现。glassfish启动时会先装载javaee.jar包中的class;但CXF需要的是geronimo-stax-api_1.0_spec-1.0.1.jar里面的com.ctc.wstx.stax.WstxOutputFactory实现类。执行时异常信息如下:
Causedby:javax.xml.stream.XMLStreamException:NamespaceURIcannotbenull
atcom.sun.xml.stream.writers.XMLStreamWriterImpl.writeAttribute(XMLStreamWriterImpl.java:632)
atorg.apache.cxf.staxutils.StaxUtils.writeElement(StaxUtils.java:520)
atorg.apache.cxf.staxutils.StaxUtils.writeElement(StaxUtils.java:440)
atorg.apache.cxf.staxutils.StaxUtils.writeDocument(StaxUtils.java:421)
atorg.apache.cxf.staxutils.StaxUtils.writeDocument(StaxUtils.java:411)
atorg.apache.cxf.staxutils.StaxUtils.writeNode(StaxUtils.java:560)
atorg.apache.cxf.transport.http.WSDLQueryHandler.writeResponse(WSDLQueryHandler.java:226)
解决办法:
在glassfish系统属性中加入javax.xml.stream.XMLOutputFactory=com.ctc.wstx.stax.WstxOutputFactory,这样就让glassfish将WstxOutputFactory作为XMLOutputFactory的实现。
可以通过glassfish的控制台菜单加入,从Configuration --> System Properties进入;或直接修改domain中config目录下的配置文件domain.xml:<domain ... <configs> <config .. ... <system-property name="javax.xml.stream.XMLOutputFactory" value="com.ctc.wstx.stax.WstxOutputFactory"/> </config> </configs> ... </domain>
修改后需要重启glassfish。这个CXF的HelloWorld在tomcat上是没有问题的,希望对glassfish的新手有点用。