-
Notifications
You must be signed in to change notification settings - Fork 51
Closed
apache/dubbo
#14837Description
dubbo版本:3.2.14
hessian版本:3.2.13
示例代码
- NatureReserveSliceService.java
public InputStream test() {
System.out.println("被调用了 返回 InputStream");
return new ByteArrayInputStream(new byte[]{21});
}
- 调用
InputStream test = sliceService.test();
- 错误信息
Caused by: org.apache.dubbo.remoting.RemotingException: com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.String
com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.String
at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:131)
at com.alibaba.com.caucho.hessian.io.AbstractMapDeserializer.readObject(AbstractMapDeserializer.java:70)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2297)
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2104)
at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:117)
at org.apache.dubbo.common.serialize.ObjectInput.readAttachments(ObjectInput.java:85)
at org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper$ProxyObjectInput.readAttachments(DefaultSerializationExceptionWrapper.java:197)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.handleAttachment(DecodeableRpcResult.java:194)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:111)
at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:153)
at org.apache.dubbo.remoting.transport.DecodeHandler.decode(DecodeHandler.java:61)
at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:49)
at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:64)
at org.apache.dubbo.common.threadpool.ThreadlessExecutor$RunnableWrapper.run(ThreadlessExecutor.java:151)
at org.apache.dubbo.common.threadpool.ThreadlessExecutor.waitAndDrain(ThreadlessExecutor.java:77)
at org.apache.dubbo.rpc.AsyncRpcResult.get(AsyncRpcResult.java:219)
at org.apache.dubbo.rpc.protocol.AbstractInvoker.waitForResultIfSync(AbstractInvoker.java:292)
at org.apache.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:194)
at org.apache.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:71)
at org.apache.dubbo.rpc.filter.RpcExceptionFilter.invoke(RpcExceptionFilter.java:40)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at com.hdi.bhd.dubbo.filter.CallServiceFilter.invoke(CallServiceFilter.java:35)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:197)
at org.apache.dubbo.rpc.protocol.ReferenceCountInvokerWrapper.invoke(ReferenceCountInvokerWrapper.java:106)
at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invokeWithContext(AbstractClusterInvoker.java:412)
at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:82)
at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:366)
at org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter.invoke(RouterSnapshotFilter.java:46)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:108)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter.invoke(MetricsClusterFilter.java:57)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:52)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
at org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter.invoke(ObservationSenderFilter.java:62)
at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:349)
....
经过debug后大致确定问题
- 代码执行到
org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream)
109行
case DubboCodec.RESPONSE_VALUE_WITH_ATTACHMENTS:
handleValue(in); // 读取返回值,进入次方法
handleAttachment(in);
break;
- 执行到
com.alibaba.com.caucho.hessian.io.Hessian2Input#readObject(java.lang.Class, java.lang.Class<?>...)
2297 行 获取InputStreamDeserializer
返序列化示例,并调用readObject
方法
Object value = findSerializerFactory().getDeserializer(expectedClass).readObject(this);
- 在
InputStreamDeserializer.readObject
调用了in.readInputStream()
- 在
com.alibaba.com.caucho.hessian.io.Hessian2Input#readInputStream
方法中读取到的tag值为65,执行case 'b':
,问题可能就在这,在这里只是读取了数据长度,并没有读取数据就结束了
case 'b': //maybe it's a mistype of BC_BINARY_CHUNK
_isLastChunk = tag == 'B';
_chunkLength = (read() << 8) + read(); // 获取数据长度
break; // 结束 switch
- 代码执行到
com.alibaba.com.caucho.hessian.io.Hessian2Input#readInputStream
方法3424行时只返回了ReadInputStream
实例,也没用读取数据就返回了 - 执行到
org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcResult#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream)
111行handleAttachment
方法时,因为前面的数据没有读取,参数in
中的_offset
值没有变化,所以导致handleAttachment
方法读取失败。
- 以上是debug得到的信息,个人觉得传输
InputStream
时应该把数据放到末尾,先读取Attachment
再读取InputStream
,因为可能InputStream
比较大
Metadata
Metadata
Assignees
Labels
No labels