Web Service 命令行工具故障诊断技巧
使用这些技巧对开发 Java™ API for XML-based RPC (JAX-RPC) Web Service 时使用的 WSDL2Java 和 Java2WSDL 命令行工具进行故障诊断。
本主题中的每个部分描述一个问题,这些问题在使用 WSDL2Java 或 Java2WSDL 工具时可能遇到。还提供了有助于对问题进行故障诊断的解决方案。
z/OS® 平台不支持 WSDL2Java 和 Java2WSDL 命令行工具。此功能由在 z/OS 平台上运行的 WebSphere® Application Server 附带的组装工具提供。请阅读有关用于“针对基于 XML 的远程过程调用的 Java API”(JAX-RPC) 应用程序的 WSDL2Java 和 Java2WSDL 命令行工具的内容,以了解有关这些工具的更多信息。
System.InvalidOperationException: Method AnnuityInteropService.wsListAnnuityByHolder cannot be reflected.
System.InvalidOperationException: There was an error reflecting wsListAnnuityByHolderResult.
System.InvalidOperationException: The Form property might not be unqualified when an explicit namespace
property is available.
在发生以下情况时,会出现该问题:服务器端方法返回了一个向量,Web 服务描述语言 (WSDL) 文件的样式是文档/文字且 Form 不合格。因为缺省情况下 elementFormDefault="unqualified",所以总是为文档/文字样式生成不合格的 Form。
.NET Framework 中存在下列问题:当 Web Service 方法包含作为参数的某些数组时,可能生成无效 Web Service 代理类。该框架将 XmlArrayAttribute 属性添加到参数,而属性构造函数包含“Form=Unqualified”和名称空间定义。当该属性有效时,将它的这两方面组合起来是无效的,会导致 System.InvalidOperationException 异常。
为避免此问题,请不要在部署到 WebSphere Application Server 中的 Web Service 方法中使用向量参数。Web Service 方法中的向量参数不使用 .Net 客户机或 Java 集合类型。
当在启用超线程的机器上运行“端点启用器”工具时,与企业应用程序项目对照的“任务”视图中会报告错误。只有在重新启动工作台之后,才能删除企业应用程序项目。
如果自动构建与 Enterprise JavaBeans (EJB) 项目验证器之间出现竞争状态,那么可发生此问题。
要解决该问题,请在运行“端点启用器”工具之前关闭工作台自动构建,然后重新打开。
当部署由 Java2WSDL 命令行工具生成的企业归档 (EAR) 文件(包含带 http、jms 和 ejb 绑定的 WSDL 文件)时发生 Java 规范请求 (JSR) 109 规范验证错误。
对于 JavaBeans 实现,JSR 109 规范要求 webservices.xml 部署描述符文件中定义的每个端口组件都引用 web.xml 文件中的唯一的 <servlet-class> 元素,对于 EJB 实现,那么要求引用 ejb-jar.xml 文件中唯一的 <session> 元素。Servlet 和会话 EJB 位于 <servlet-link> 或 <ejb-link> 元素表示的 webservices.xml 文件中。
WSDL2Java 命令行工具将 WSDL 文件中找到的端口映射到生成的 webservices.xml 文件中的端口组件。如果单个 Web Service 具有多个绑定,那么除了这些绑定中的每个绑定都有对应端口外,webservices.xml 文件还包含多个端口组件,这些端口组件应当指向同一个 EJB 模块 (<session>) 或 JavaBeans (<servlet-class>) 实现。由于 JSR 109 限制,webservices.xml 文件将无效并且在部署过程中会发生错误。
Error in <module> : CHKW6030E: Implementation class <class> referred to by port
components<port1> and <port2>. (JSR109 1.0: 7.1.2).
这里是带样本数据的错误:Error in WebSvcsInSession20EJB.jar : CHKW6030E: Implementation class WSMultiProtocol
referred to by port components WSMultiProtocolJMS and WSMultiProtocolEJB.(JSR109 1.0: 7.1.2).
您可以通过在 ejb-jar.xml 文件中创建都指向同一实现类、Home 接口和远程接口的多个 <session> EJB 定义来解决限制。您仍可使用相同的类,但必须复制引用类和接口的 ejb-jar.xml 文件 <session> 定义。
<webservices>
<webservice-description>
<webservice-description-name>WSMultiProtocolService</webservice-description-name>
<wsdl-file>META-INF/wsdl/WSMultiProtocol.wsdl</wsdl-file>
<jaxrpc-mapping file>META-INF/WSMultiProtocol_mapping.xml</jaxrpc-mapping file>
<port-component>
<port-component-name>WSMultiProtocolEjb</port-component-name>
<wsdl-port>
<namespaceURI>http://ejb.pli.tc.wssvt.ibm.com</namespaceURI>
<localpart>WSMultiProtocolEjb</localpart>
</wsdl-port>
<service-endpoint-interface>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol
</service-endpoint-interface>
<service-impl-bean>
<ejb-link>WSMultiProtocol</ejb-link>
</service-impl-bean>
</port-component>
<port-component>
<port-component-name>WSMultiProtocolJMS</port-component-name>
<wsdl-port>
<namespaceURI>http://ejb.pli.tc.wssvt.ibm.com</namespaceURI>
<localpart>WSMultiProtocolJMS</localpart>
</wsdlport>
<service-endpoint-interface>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol
</service-endpoint-interface>
<service-impl-bean>
<ejb-link>WSMultiProtocol_2</ejb-link>
</service-impl_bean>
</port-component>
<port-component>
<port-component-name>WSMultiProtocolJMS</port-component-name>
<wsdl-port>
<namespaceURI>http://ejb.pli.tc.wssvt.ibm.com</namespaceURI>
<localpart>WSMultiProtocolJMS</localpart>
</wsdlport>
<service-endpoint-interface>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol
</service-endpoint-interface>
<service-impl-bean>
<ejb-link>WSMultiProtocol_3</ejb-link>
</service-impl_bean>
</port-component>
</webservice-description>
</webservices>
以下是 ejb-jar.xml 文件的示例。查找类和接口以及复制它们的方法:<ejb-jar-id="ejb-jar_ID">
<display-name>WebSvcsInsSession20EJB</display-name>
<enterprise-beans>
<session-id="WSMultiProtocol">
<ejb-name>WSMultiProtocol</ejb-name>
<home>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol</remote>
<ejb-class>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolWebSvcsBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref-id="EjbRef_1082407586720">
<description></description>
<ejb-ref-name>ejb/BeneficiarySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.BeneficiarySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.BeneficiarySession</remote>
<ejb-link>PolicySession20EJB.jar#BeneficiarySession</ejb-link>
</ejb-ref>
<ejb-ref-id="EjbRef_1082407586790">
<description></description>
<ejb-ref-name>ejb/PolicySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.PolicySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.PolicySession</remote>
<ejb-link>PolicySession20EJB.jar#PolicySession</ejb-link>
</ejb-ref>
<session-id="WSMultiProtocol_2">
<ejb-name>WSMultiProtocol_2</ejb-name>
<home>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol</remote>
<ejb-class>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolWebSvcsBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref-id="EjbRef_1082407586720_2">
<description></description>
<ejb-ref-name>ejb/BeneficiarySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.BeneficiarySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.BeneficiarySession</remote>
<ejb-link>PolicySession20EJB.jar#BeneficiarySession</ejb-link>
</ejb-ref>
<ejb-ref-id="EjbRef_1082407586790_2">
<description></description>
<ejb-ref-name>ejb/PolicySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.PolicySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.PolicySession</remote>
<ejb-link>PolicySession20EJB.jar#PolicySession</ejb-link>
</ejb-ref>
<session-id="WSMultiProtocol_3">
<ejb-name>WSMultiProtocol_3</ejb-name>
<home>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocol</remote>
<ejb-class>com.ibm.wssvt.tc.pli.ejb.WSMultiProtocolWebSvcsBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref-id="EjbRef_1082407586790_3">
<description></description>
<ejb-ref-name>ejb/BeneficiarySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.BeneficiarySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.BeneficiarySession</remote>
<ejb-link>PolicySession20EJB.jar#BeneficiarySession</ejb-link>
</ejb-ref>
<ejb-ref-id="EjbRef_1082407586790_3">
<description></description>
<ejb-ref-name>ejb/PolicySession</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.ibm.wssvt.tc.pli.ejb.PolicySessionHome</home>
<remote>com.ibm.wssvt.tc.pli.ejb.PolicySession</remote>
<ejb-link>PolicySession20EJB.jar#PolicySession</ejb-link>
</ejb-ref>
</session>
如果应用程序使用了特定修订提供的功能,而您移除了该修订,那么应用程序会显示错误消息。如果您移除修订,那么确保重新测试应用程序以检查是否会发生错误。重新部署由于丢失修订而显示错误消息的任何应用程序。
例如,假设您在 WebSphere Application Server 上安装了修订包并创建了股票行情 Web Service StockQuote。WSDL2Java 命令行工具用于部署程序角色中,生成扩展 AgnosticService 类的 ServiceLocator 类。
java.lang.NoClassDefFoundError:
Error while defining class:
com.ibm.ws.wsfvt.test.stockquote.StockQuoteServiceLocator
This error indicates that the class:
com.ibm.webservices.multiprotocol.AgnosticService
could not be located while defining the class:
com.ibm.ws.wsfvt.test.stockquote.StockQuoteServiceLocator
需要在 WebSphere Application Server 上重新部署应用程序,以发布不使用该 WebSphere Application Server 版本的代码,因为所用 Web Service 类不支持该版本。如果您在运行 WSDL2Java 命令期间使用需要代理服务器访问因特网的环境,那么 WSDL2Java 命令可能找不到因特网信息,因为代理服务器可能超时。例如,如果输入 WSDL 文件位于因特网而非本地驱动器且您需要从因特网获取它,那么 WSDL2Java 命令找不到该文件,因为代理服务器超时。
当使用 Windows 操作系统时,可以通过编辑 WSDL2Java.bat 文件解决此问题,或者当使用 Linux 或 AIX® 操作系统时,可以通过编辑 WSDL2Java.sh 文件解决此问题。这些文件位于 <install_root>/WebSphere/AppServer/bin 目录。
![[Windows]](../images/windows.gif)
![[z/OS]](../images/ngzos.gif)
PROXY_INFO="-Dproxy.httpHost=yourPproxyHost -Dproxy.httpPort=yourProxyPort
![[Linux]](../images/linux.gif)
![[AIX]](../images/aixlogo.gif)
![[HP-UX]](../images/hpux.gif)
![[Solaris]](../images/solaris.gif)
![[z/OS]](../images/ngzos.gif)
PROXY_INFO="-Dproxy.httpHost=yourProxyHost -Dproxy.httpPort=yourProxyPort
![[IBM i]](../images/iseries.gif)
- 编辑 profile_root/bin/WSDL2Java 文件并将下行添加到该文件的开头:
如果使用此选项,那么必须调用 profile_root/bin 目录中的 WSDL2Java 命令。export PROXY_INFO="-Dproxy.httpHost=yourProxyHost -Dproxy.httpPort=yourProxyPort"
- 在调用 WSDL2Java 命令之前,在 Qshell 会话中设置 PROXY_INFO 环境变量,如下所示:
如果使用此选项,那么在每次启动新的 QSHELL 会话时,都需要运行该命令。如果不需要每次都启动 QSHELL,那么可以将该命令添加到概要文件。$ export PROXY_INFO ="-Dproxy.httpHost=yourProxyHost -Dproxy.httpPort=yourProxyPort"
如果您在包含 JMS 样式端点 Web 地址(例如 jms:/...)的 WSDL 文档上运行 WSDL2Java 命令行工具,那么包含 JMS 协议的定制协议处理程序的 urlprotocols.jar 文件一定要在 CLASSPATH 变量语句中。错误 WSWS3099E: 错误:发射器故障。端口 <x>,服务 <y>: <jms-url-string> 的端点地址无效,可以通过确保 urlprotocols.jar 文件在 CLASSPATH 变量语句中来避免此错误。
要将 urlprotocols.jar 文件添加到 CLASSPATH 变量语句:
在 Windows 平台上,编辑 install_root\bin\setupCmdLine.bat 文件并找到设置 WAS_CLASSPATH 环境变量的行。将 %install_root%\lib\urlprotocols.jar 添加到设置 WAS_CLASSPATH 环境变量的那一行结尾。
在 Linux、AIX、HP-UX 以及 Solaris 操作系统上,编辑 install_root/bin/setupCmdLine.sh 文件并将 $install_root/lib/urlprotocols.jar 添加到设置 WAS_CLASSPATH 环境变量的那一行末尾。
请确保对您的平台使用正确的定界符字符,例如,分号 (;) 用于 Windows 平台,冒号 (:) 用于 Linux、AIX、HP-UX 以及 Solaris 操作系统。