关于axis2发布服务,用cxf在同个进程调用不同服务时出现数组下标越界问题

xiaoxiao2021-02-27  288

有时候我们在同一个方法调用多个webservice的时候,有可能会报数组下标越界问题,出现该问题主要是因为发布webservice时在service.xml使用了同样的schemaNamespace导致的。

问题重现: (1)、在axis2中发布了两个webservice:query_log_lzj和insert_log_lzj:

并且这两个webservice的service.xml配置文件的schemaNamespace都是相同的:

(2)、在同一个方法中调用这两个服务,代码如下:

如果运行上面的main函数,将会得到如下错误:

原因分析: 后来通过跟踪cxf调用服务的源码发现了问题: (1)、当cxf调用服务代码时,cxf会为每个服务在本地(我本地的生成目录:C:\Users\gosunAdmin\AppData\Local\Temp\org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory@69254fcd-1493881837654-src\test\lzj\com\dataservice)生成几个java文件(具体生成源码可以查看cxf-rt-databinding-jaxb-2.5.9-sources.jar包的DynamicClientFactory.java的createClient方法),应该是服务类的代理类,然后会把这几个java文件编译成class(class保存目录:C:\Users\gosunAdmin\AppData\Local\Temp\org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory@69254fcd-1493881837654-classes)(这些源码和编译后的class,在使用完的时候会马上删除): 每个服务cxf都会生成的java文件有如下几个:

其中有个ObjectFacroty的类,这个类的内容如下: query_log_lzj服务的ObjectFactory内容如下: insert_log_lzj服务的ObjectFactory内容如下:

问题就出在这个ObjectFactory类,当调用第一个服务的时候,比如调用query_log_lzj这个服务,代码中能够正确加载对应的ObjectFactory,所以调用第一个服务时是没有问题的。但是调用第二个服务insert_log_lzj时,cxf使用的ObjectFactory代码依然是query_log_lzj服务的ObjectFactory内容,也就是说调用第二个服务的时候用错了ObjectFactory,这就造成了调用insert_log_lzj服务的方法时找不到对应的方法,因为query_log_lzj的ObjectFactory没有insert_log_lzj服务应有的方法,导致在后续的查找可调用方法时查找不到相应的方法,就报数组下标越界异常,导致服务调用失败(因为可以调用的方法会保存在一个方法数组里)。

知道这原因之后,原本以为是cxf的代码bug,可是通过查看源码,根本无从下手去修改,后来通过修改服务配置文件service.xml,把query_log_lzj、insert_log_lzj这两个服务的schemNamespace设置 成不一样,问题居然解决了。 个人感觉有可能是cxf内部的机制问题,或许是同样的约束空间不会重新加载ObjectFactory。 目前尚无法解释具体原因,只知道这样能解决该问题,如果有哪位大神遇到这种情况,知道具体原因,有更好的解决办法,希望能留言。

转载请注明原文地址: https://www.6miu.com/read-3931.html

最新回复(0)