开发者社区 > 云原生 > 正文

方法参数对象中有LinkedBlockingQueue序列化问题

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

展开
收起
大圣东游 2023-05-11 20:15:17 128 0
1 条回答
写回答
取消 提交回答
  • 应该是 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

    2023-05-12 12:13:54
    赞同 展开评论 打赏

阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载