Dubbo version: 2.7.2 Operating System version: win10 Java version: jdk1.8.101
按基本方式定义好接口及实现 在接口方法中使用一个Serializable对象,在该对象中应用一个LinkedBlockingQueue变量,具体见下TestQueue定义 协议为默认的dubbo协议 运行服务,服务端出错,不能正常传输有LinkedBlockingQueue变量的值。 对象定义:
public class TestQueue implements Serializable { ...... private BlockingQueue queue = new LinkedBlockingQueue<>(); .... }
接口定义:
public interface RemoteCallService { .... TestQueue addQueue(String name, TestQueue queue); ...... }
客户端调用后,服务端出现的错误为:
[WARN ][NettyServerWorker-5-1][DecodeableRpcInvocation] [DUBBO] Decode argument failed: com.o2o.remote.domain.TestQueue.queue: java.util.ArrayList ([quueu]) cannot be assigned to 'java.util.concurrent.BlockingQueue', dubbo version: 2.7.2, current host: 192.168.1.126 com.alibaba.com.caucho.hessian.io.HessianFieldException: com.o2o.remote.domain.TestQueue.queue: java.util.ArrayList ([quueu]) cannot be assigned to 'java.util.concurrent.BlockingQueue' at com.alibaba.com.caucho.hessian.io.JavaDeserializer.logDeserializeError(JavaDeserializer.java:171) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:410) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:276) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:203) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2818) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2145) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2074) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2118) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2074) ~[dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:92) ~[dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:116) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:73) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:132) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:122) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:82) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:48) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder.decode(NettyCodecAdapter.java:90) [dubbo-2.7.2.jar:2.7.2] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.25.Final.jar:4.1.25.Final] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151] Caused by: java.lang.IllegalArgumentException: Can not set java.util.concurrent.BlockingQueue field com.o2o.remote.domain.TestQueue.queue to java.util.ArrayList at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[?:1.8.0_151] at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[?:1.8.0_151] at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[?:1.8.0_151] at java.lang.reflect.Field.set(Field.java:764) ~[?:1.8.0_151] at com.alibaba.com.caucho.hessian.io.JavaDeserializer$ObjectFieldDeserializer.deserialize(JavaDeserializer.java:408) ~[dubbo-2.7.2.jar:2.7.2] ... 33 more [2019-07-10 09:40:42.402][WARN ][NettyServerWorker-5-1][DecodeableRpcInvocation] [DUBBO] Decode rpc invocation failed: expected map/object at java.lang.String (abc), dubbo version: 2.7.2, current host: 192.168.1.126 com.alibaba.com.caucho.hessian.io.HessianProtocolException: expected map/object at java.lang.String (abc) at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.error(AbstractDeserializer.java:131) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.AbstractMapDeserializer.readObject(AbstractMapDeserializer.java:70) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2267) ~[dubbo-2.7.2.jar:2.7.2] at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2074) ~[dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:92) ~[dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:126) ~[dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:73) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:132) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:122) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:82) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:48) [dubbo-2.7.2.jar:2.7.2] at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder.decode(NettyCodecAdapter.java:90) [dubbo-2.7.2.jar:2.7.2] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-all-4.1.25.Final.jar:4.1.25.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.25.Final.jar:4.1.25.Final] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_151]
原提问者GitHub用户greatle
应该是 com.alibaba.hessian-lite 包反序列化的时候处理有问题,这个 case 里面反序列化会走如下逻辑:
@Override public Object readObject(Class expectedClass, Class<?>... expectedTypes) throws IOException { if (expectedClass == null || expectedClass == Object.class) return readObject();
int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
switch (tag) {
...
case 0x77: {
int length = tag - 0x70;
String type = readType();
Deserializer reader;
reader = findSerializerFactory().getListDeserializer(null, expectedClass);
boolean valueType = expectedTypes != null && expectedTypes.length == 1;
// fix deserialize of short type
Object v = reader.readLengthList(this, length, valueType ? expectedTypes[0] : null);
return v;
}
...
}
注意看如下两行代码:
String type = readType(); Deserializer reader; reader = findSerializerFactory().getListDeserializer(null, expectedClass);
这里 type 是 LinkedBlockingQueue,expectedClass 是 BlockingQueue,reader 是 com.alibaba.com.caucho.hessian.io.CollectionDeserializer 类型,这样的话reader._type 就是 BlockingQueue,所以导致后面调用 com.alibaba.com.caucho.hessian.io.CollectionDeserializer#createList 方法时返回的是一个 ArrayList 实例,从而导致赋值失败。从这个地方推断,其他类似情况也会反序列化异常;个人认为解决办法有两种:
直接将 queue 定义为 LinkedBlockingQueue 类型,经测试可行 2.修改 hessian-lite 里面 Hessian2Input 2245 行 reader = findSerializerFactory().getListDeserializer(null, expectedClass); expectedClass 换成 type 指定的类型应该也可以解决问题
原回答者GitHub用户kexianjun
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。