apache / dubbo-hessian-lite

Hessian Lite for Apache Dubbo
Apache License 2.0
53 stars 47 forks source link

dubbo协议反序列化EnumSet类出错 #15

Closed efanhome closed 5 years ago

efanhome commented 9 years ago

使用dubbo协议,暴露的接口参数中含有EnumSet,消费端调用传入值后(EnumSet.of(e)),服务端收到的值为null,详细的异常信息:

java.lang.UnsupportedOperationException: com.alibaba.com.caucho.hessian.io.CollectionDeserializer@1360218
    at com.alibaba.com.caucho.hessian.io.AbstractDeserializer.readObject(AbstractDeserializer.java:103)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2067)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1592)
    at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1576)
    at com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:94)
    at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:109)
    at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:71)
    at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:137)
    at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:128)
    at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:87)
    at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:49)
    at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.messageReceived(NettyCodecAdapter.java:135)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:80)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:44)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
wuwen5 commented 9 years ago

http://dubbo.io/Serialization+Issues-zh.htm 1.hessian 序列化不支持反序列化 java.util.EnumSet,dubbo协议默认使用 hessian 做序列化。

可以参考 https://github.com/alibaba/dubbo/pull/121

efanhome commented 9 years ago

原生的hessian在4.0.3版修复了此问题,详细的可以移步这里看下。

dubbo内嵌的hessian版本是3.2.1-fixed-2

使用hessian协议+原生hessian反序列化可避免此问题,但会出现如下类似警告信息

警告: Hessian/Burlap: 'java.lang.Enum' is an unknown class in sun.misc.Launcher$AppClassLoader@27c170f0:
java.lang.RuntimeException: Class java.lang.Enum is not an enum
wuwen5 commented 9 years ago

是的,我就是从这里拷过来测试的,改了一个地方消除了警告,可以运行单元测试。 另外hessian 4.0.3源码包中没有看到这段修改,比较奇怪

efanhome commented 9 years ago

那是网友自己写的patch,他自己说可能某种程度上说不是好的解决方式

It's not a proper fix by any means, but it's good enough for me to make forward progress while I wait for a "real" fix from an actual developer...

hessian官方在版本4.0.3,接口Deserializer加了3个方法 public Object[] createFields(int len) Object createField(String name) Object readObject(AbstractHessianInput in, Object []fields) throws IOException 由此改了一大堆方法,有兴趣你可以研究下咯 -_-||

wuwen5 commented 9 years ago

@efanhome 我看了下hessian 4.0.3 是新增的UnsafeDeserializer来支持了EnumSet的反序列化。

如果不直接升级到4.0.x版本的话也可以修改下SerializerFactory,合入UnsafeDeserializer\UnsafeSerializer 这部分来支持

efanhome commented 9 years ago

@wuwen5 谢谢告知,你的求知欲比我高许多,向你学习 :+1:

LuckyDevin commented 5 years ago

👍