webservice调用异常

时间:2024-03-13 14:41:50

今天遇到一个通过cxf框架实现webservice调用的问题,百度等搜索以后没找到解决问题的方法,所以将解决方法分享出来,希望对大家有所帮助。

1.现象描述:

通过webservice方式执行方法WfPackage getPackage(String pkgId)时,在方法返回时抛出异常。

2014-04-08 14:33:00,244: EXCEPTION

java.lang.*Error

        at java.nio.ByteOrder.nativeOrder(ByteOrder.java:56)

        at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:313)

        at org.mortbay.io.nio.DirectNIOBuffer.poke(DirectNIOBuffer.java:201)

        at org.mortbay.io.nio.DirectNIOBuffer.poke(DirectNIOBuffer.java:141)

        at org.mortbay.io.AbstractBuffer.put(AbstractBuffer.java:448)

        at org.mortbay.jetty.HttpGenerator.addContent(HttpGenerator.java:148)

        at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:644)

        at org.mortbay.jetty.AbstractGenerator$Output.write(AbstractGenerator.java:579)

        at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:46)

        at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:96)

        at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:184)

        at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:311)

        at org.apache.cxf.aegis.xml.stax.ElementWriter.close(ElementWriter.java:165)

        at org.apache.cxf.aegis.type.basic.BeanType.writeElement(BeanType.java:398)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObjectInternal(BeanType.java:380)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObject(BeanType.java:320)

        at org.apache.cxf.aegis.type.basic.BeanType.writeElement(BeanType.java:396)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObjectInternal(BeanType.java:380)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObject(BeanType.java:320)

        at org.apache.cxf.aegis.type.basic.BeanType.writeElement(BeanType.java:396)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObjectInternal(BeanType.java:380)

        at org.apache.cxf.aegis.type.basic.BeanType.writeObject(BeanType.java:320)

//----xxx此处省略n----------------

 

2014-4-8 14:33:01 org.apache.cxf.phase.PhaseInterceptorChain doIntercept

信息: Interceptor has thrown exception, unwinding now

org.apache.cxf.interceptor.Fault: Can't overwrite cause

        at org.apache.cxf.aegis.databinding.XMLStreamDataReader.read(XMLStreamDataReader.java:62)

        at org.apache.cxf.aegis.databinding.XMLStreamDataReader.read(XMLStreamDataReader.java:38)

        at org.apache.cxf.interceptor.DocLiteralInInterceptor.getPara(DocLiteralInInterceptor.java:235)

        at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:120)

 

//----xxx此处省略n----------------

Caused by: java.lang.IllegalStateException: Can't overwrite cause

        at java.lang.Throwable.initCause(Throwable.java:320)

        at com.ctc.wstx.compat.Jdk14Impl.setInitCause(Jdk14Impl.java:70)

        at com.ctc.wstx.exc.WstxException.<init>(WstxException.java:46)

        at com.ctc.wstx.exc.WstxIOException.<init>(WstxIOException.java:16)

        at com.ctc.wstx.sr.StreamScanner.throwFromIOE(StreamScanner.java:683)

        at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1086)

        at org.apache.cxf.staxutils.DepthXMLStreamReader.next(DepthXMLStreamReader.java:220)

        at org.apache.cxf.aegis.xml.stax.ElementReader.getValue(ElementReader.java:136)

        at org.apache.cxf.aegis.type.basic.StringType.readObject(StringType.java:36)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.ArrayType.readCollection(ArrayType.java:86)

        at org.apache.cxf.aegis.type.collection.CollectionType.readObject(CollectionType.java:52)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.ArrayType.readCollection(ArrayType.java:86)

        at org.apache.cxf.aegis.type.collection.CollectionType.readObject(CollectionType.java:52)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:161)

        at org.apache.cxf.aegis.type.basic.ArrayType.readCollection(ArrayType.java:86)

        at

 

//----xxx此处省略n----------------

 

2.分析:

从异常看,是因为方法栈调用陷入了死循环,导致栈内存溢出,应该服务器端执行完,WfPackage接口的实例通过aegis序列化成xml时导致了死循环。

下面看一下WfPackage代码片段:


webservice调用异常
 

 

WfProcessDefinition代码片段:

 

 
webservice调用异常
 

WfActivityDefinition代码片段:

 

 
webservice调用异常
 

WfTransition代码片段:

 

 
webservice调用异常
 

其中类WfPackage依赖了WfProcessDefinition, WfProcessDefinition依赖了WfActivityDefinition,

对象WfActivityDefinition依赖了WfTransitionWfTransition又依赖了WfActivityDefinition,存在循环依赖。

初步怀疑是这个问题导致的。

 

WfTransition中的

 

    /**

     * 目标活动

     */

    public WfActivityDefinition getToActivity();

    /**

     * 源活动

     */

    public WfActivityDefinition getFromActivity();

 

改为:

 

       /**

     * 目标活动

     */

    public String getToActDefId();

    /**

     * 源活动

     */

    public String getFromActDefId();

 

    返回活动定义的Id

 

去掉了WfTransition中对WfActivityDefinition的依赖。

 

去掉后,问题解决,测试通过。

 

3.其他:

看来aegis数据绑定,除了下面几个约束外,还不允许类的循环依赖。

1.入参、出参如果是集合类型,必须使用泛型,集合中的对象类型的属性、方法中如果有集合类型,也必须使用泛型标识出具体的类型,这个一直到递归到底。

2.必须有settergetter方法,有settergetter方法的话,必须有这个属性。