WSDL parsing exception creating Webservice client with CXF J



我已经编写了一些代码来使用CXF创建和运行Web服务客户端。我使用 JaxWsClientFactoryBean(不确定它是最好的解决方案)从 .wsdl 文件创建客户端。这里的目标是以编程方式避免春天等。只是使用Java和CXF的纯代码。

JaxWsClientFactoryBean cfb = new JaxWsClientFactoryBean();
cfb.setAddress(getServiceProperty(intClass, PROPERTY_KEY_URL_SUFFIX));
cfb.setServiceClass(intClass);
cfb.setOutInterceptors(getOutInterceptors(intClass));
cfb.setServiceName(SERVICE_NAME);
cfb.setWsdlURL("classpath:wsdl/" + intClass.getSimpleName() + ".wsdl");
cfb.setEndpointName(ENDPOINT_NAME);
Client client = cfb.create();
ClientProxy cp = new ClientProxy(client);
I intService = (I) 
   Proxy.newProxyInstance(intClass.getClassLoader(), new Class[] { intClass }, cp);

我真的不确定这是否正确完成,但是当我在本地运行此代码并在 Tomcat 上部署它时,它可以工作。

不幸的是,我需要在Weblogic上运行此代码,这会导致奇怪的异常:

Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was
made to insert a node where it is not permitted.
        at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:235)
        at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:186)
        at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:92)
        ... 26 more
Caused by: org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
        at com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore(ParentNode.java:356)
        at com.sun.org.apache.xerces.internal.dom.ParentNode.insertBefore(ParentNode.java:284)
        at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:399)
        at com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild(NodeImpl.java:235)
        at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:1019)
        at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:939)
        at org.apache.cxf.staxutils.StaxUtils.read(StaxUtils.java:866)
        at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:226)
        ... 28 more

这在应用程序部署期间发生。看起来.wsdl文件有问题,但是等等...它正在制作雄猫!

我认为 Weblogic 及其 JRockit VM 和标准 JVM 中的 com.sun.org.apache.xerces.* 类实现可能存在一些差异,但我不知道如何解决它。

我花了很多时间尝试不同的客户端创建方式。他们中的大多数人在本地和Tomcat中工作,但没有一个在WebLogic上工作。

有什么提示接下来要尝试什么吗?我有点厌倦了这个话题:D

我同意您的怀疑,即该问题与使用的 Xerces 版本有关。堆栈跟踪显示,在您的案例中使用了 Xerces 的 Sun 实现,它是 Apache Xerces 的衍生物。

请查看与 WebLogic 相关的 Apache CFX Application Server Configuration Guide 说明。

WebLogic ClassLoading

在 WebLogic Server 中,系统类路径中存在的任何.jar文件都由 WebLogic Server 系统类装入器装入。在服务器实例中运行的所有应用程序都装入于应用程序类装入器中,这些应用程序类装入器是系统类装入器的子级。在系统类装入器的此实现中,应用程序不能使用系统类装入器中已存在的不同版本的第三方 jar。每个子类装入器都向父类(系统类装入器)请求特定类,并且无法装入父类看到的类。

例如,如果一个名为 com.foo.Baz 的类同时存在于$CLASSPATH和应用程序 EAR 中,则加载来自$CLASSPATH的类,而不是来自 EAR 的类。由于 weblogic.jar 位于$CLASSPATH中,因此应用程序不能覆盖任何 WebLogic Server 类。

为了使用Xerces的替代版本,您必须创建一个FilteringClassLoader。

FilteringClassLoader 的用法

FilteringClassLoader 提供了一种机制,用于配置部署描述符,以显式指定某些包应始终从应用程序装入,而不是由系统类装入器装入。这允许您使用应用程序的替代版本,例如 Xerces 和 Ant。

FilteringClassLoader 位于应用程序类装入器和系统之间。它是系统类装入器的子级和应用程序类装入器的父级。FilteringClassLoader 截获 loadClass(String className) 方法,并将 className 与 weblogic-application.xml 文件中指定的包列表进行比较。

总之,请检查 Apache CFX 应用程序服务器配置指南中包含的步骤,并注意显式指定从应用程序装入org.apache.xerces.*包,而不是从系统类装入器装入

例如,META-INF 中的 weblogic-application.xml 文件应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
    <application-param>
        <param-name>webapp.encoding.default</param-name>
        <param-value>UTF-8</param-value>
    </application-param>
    <prefer-application-packages>
        <package-name>javax.jws.*</package-name>
        <package-name>org.apache.xerces.*</package-name>
    </prefer-application-packages>
</weblogic-application>

我希望这有所帮助。

最新更新