关于axis2发布服务,用cxf在同个进程调用不同服务时出现数组下标越界问题
2017-05-04 15:24
441 查看
有时候我们在同一个方法调用多个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。
目前尚无法解释具体原因,只知道这样能解决该问题,如果有哪位大神遇到这种情况,知道具体原因,有更好的解决办法,希望能留言。
问题重现:
(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。
目前尚无法解释具体原因,只知道这样能解决该问题,如果有哪位大神遇到这种情况,知道具体原因,有更好的解决办法,希望能留言。
相关文章推荐
- CXF发布webService、tomcat用户验证、axis2(http/https)调用服务
- 关于调用Web服务引用方式不同的问题
- 关于调用Web服务引用方式不同的问题
- 关于C#下写的Web Service 服务在Delphi下调用时的问题
- 在服务中调用外部的窗体程序出现的问题(转载)
- 解决win7下发布的WCF服务出现的Http不能注册的问题,附上我的小工具
- 关于解决在.Net中调用Excel对象后关闭Excel进程的问题
- CXF之使用jaxws API 发布服务与进行客户端调用
- [IIS问题类]Service Unavailable错误,'DefaultAppPool' 相关,(应用程序池 'DefaultAppPool' 被自动禁用,原因是为此应用程序池提供服务的进程中出现一系列错误)
- 关于调用WCF服务后Close的问题
- C#调用Java端Web服务(CXF)时发生Integer参数类型无法传递的问题
- 数组下标为负数出现的问题(关于数组下标越界的检查)
- 关于调用WEB服务超时的问题
- CXF之使用工厂方法(java代码)发布服务与进行客户端调用
- iis6应用程序池被自动禁用问题 Service Unavailable 应用程序池 'DefaultAppPool' 被自动禁用,原因是为此应用程序池提供服务的进程中出现一系列错误。应用程序-特定 权限设置未将 COM 服务器应用程序(CLSID 为
- 关于linq to sql调用存储过程,出现"无法枚举查询结果多次"的问题
- 关于axis发布服务的问题,急求帮助!
- 关于C#程序调用AMFPHP服务的问题!!
- 关于return false;在不同ie中出现的问题
- 关于桌面进程出现问题的部分解决方案