发现XFire1.2.6两个bug

本文记录了在调试ALE接口define方法时遇到的两个bug及解决过程。一是由于自动生成的代码缺少setter方法导致异常;二是因为Boolean类型的setter方法未被正确识别。通过对代码的深入分析找到了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两个bug是在调试ALE接口中define方法时发现,

BUG1

步骤:
WS调用define方法,定义一个ECSpec

现象:
抛出异常信息,说某类的属性没有“写方法”(setter),见如下异常堆栈信息:


[handler.DefaultFaultHandler]-[INFO] Fault occurred!
org.codehaus.xfire.fault.XFireFault: No write method for property {http://_1.xsd.ale.epcglobal}excludePattern in class epcglobal.ale.xsd._1.ECExcludePatterns
at org.codehaus.xfire.aegis.type.basic.BeanType.writeProperty(BeanType.java:283)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:167)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.type.basic.ArrayType.readCollection(ArrayType.java:80)
at org.codehaus.xfire.aegis.type.collection.CollectionType.readObject(CollectionType.java:36)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:169)
at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:206)
at org.codehaus.xfire.service.binding.WrappedBinding.readMessage(WrappedBinding.java:51)
at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64)
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)
at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:304)
at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:129)
at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
at java.lang.Thread.run(Thread.java:595)

分析:
org.codehaus.xfire.fault.XFireFault: No write method for property {http://_1.xsd.ale.epcglobal}excludePattern in class epcglobal.ale.xsd._1.ECExcludePatterns
经发现,epcglobal.ale.xsd._1.ECExcludePatterns确实没有为excludePattern 提供setter方法。
epcglobal.ale.xsd._1.ECExcludePatterns并不是由手工编写,而是通过XFire的eclipse插件根据 ALE.xsd文件自动生成。因此,初步推断很可能是自动生成代码的组件没有能够为excludePattern提供setter方法,后对比其它自动生 成的代码发现,只有集合类的属性不会提供setter方法;进一步思考发现:

@XmlElement(required = true)
protected List<string> excludePattern;</string>
<string> </string>
<string> 集合类属性通常对应于XSD中元素的概念,如上述代码中,“@XmlElement”的注释就就说明了excludePattern在xml是一个元素。 根据这个思路推断,自动代码生成的规则对“@XmlElement”只会生成getter方法,不提供setter方法。</string>
<string></string>
<string>
解决:
</string>
<string> 手工添加setter方法解决,这个应用上的bug。 </string>
<string></string>
<string>
BUG1

步骤:
</string>
<string> 同上</string>
<string></string>
<string> 现象:
</string>
<string> 同上</string>
<string></string>
<string>
</string>
<string> 2007-11-19 19:59:43 [handler.DefaultFaultHandler]-[INFO] Fault occurred!</string>
<string> org.codehaus.xfire.fault.XFireFault: No write method for property {http://_1.xsd.ale.epcglobal}includeSpecInReports in class epcglobal.ale.xsd._1.ECSpec</string>
<string> at org.codehaus.xfire.aegis.type.basic.BeanType.writeProperty(BeanType.java:283)</string>
<string> at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:167)</string>
<string> at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)</string>
<string> at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:169)</string>
<string> at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:206)</string>
<string> at org.codehaus.xfire.service.binding.WrappedBinding.readMessage(WrappedBinding.java:51)</string>
<string> at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)</string>
<string> at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)</string>
<string> at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64)</string>
<string> at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)</string>
<string> at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:304)</string>
<string> at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:129)</string>
<string> at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116)</string>
<string> at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)</string>
<string> at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)</string>
<string> at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)</string>
<string> at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)</string>
<string> at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)</string>
<string> at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)</string>
<string> at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)</string>
<string> at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)</string>
<string> at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)</string>
<string> at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)</string>
<string> at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)</string>
<string> at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)</string>
<string> at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)</string>
<string> at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)</string>
<string> at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)</string>
<string> at java.lang.Thread.run(Thread.java:595)</string>
<string></string>
<string>
分析:
</string>
<string> 根据bug1的分析思路发现,epcglobal.ale.xsd._1.ECSpec类中为includeSpecInReports提供了setter方法,而为什么还会抛出没有写方法的错误呢?这让相当费解......</string>
<string> </string>
<string> 多次单步调试源代码没有发现代码上的疑问,还是只能对比其它自动生成的类。终于意外发现,自动代码生成的时候,对其基本数据类型(int、long等) 中,唯有boolean的类型在对应到java中Boolean类型,而不像long直接对应于java中long,我试探性的将代码中Boolean改 为boolean,并修改了对应的setter方法,再次调用问题解决。</string>
<string> </string>
<string> 问题虽解决了,但没有道理应为是Boolean就不能识别其setter方法。呵呵,我忽略了方法的参数,尽管不论是Boolean还是boolean,它们的setter方法名都是setIncludeSpecInReports</string>
<string> ,可是它们方法的参数类型不同,那么XFire通过反射调用方法时不光识别方法名,还对参数类型也进行了对比,这也是合乎情理的,毕竟方法是可以重载的。</string>
<string></string>
<string>
解决:
</string>
<string> 修改Boolean为boolean,且修改对应的setter方法。</string>
<string></string>
<string>


总结:
</string>
<string> 上述两个BUG都没有根除问题,那是因为需要修正XFire的源代码,这个手术就复杂啦,还是留给XFire的开源团队来解决吧。</string>
<string> 另外,在流行的开源组件、框架也好,它们也不可能摆脱BUG的梦魇,当发现BUG时,发呆是没有用的,搞来源代码调试分析,总能找到答案。</string>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值