zoukankan      html  css  js  c++  java
  • Dubbo序列化多个CopyOnWriteArrayList对象变成同一对象的一个大坑!!

    环境:

      win10 + jdk 1.8 + dubbo 2.5.10

    问题描述:

      当一个对象(此对象内包含多个CopyOnWriteArrayList对象) 作为参数调用RPC接口后, 服务提供者拿到的对象中的CopyOnWriteArrayList, 引用都相同了(即变成了同一个对象).

    问题范围缩小:

     Dubbo Serialization 反序列化时会有此问题, 用一下代码可以重现问题

      

    import com.alibaba.dubbo.common.serialize.support.dubbo.GenericObjectInput;
    import com.alibaba.dubbo.common.serialize.support.dubbo.GenericObjectOutput;
    
    import java.io.*;
    
    /**
     *
     * Dubbo序列化的一个坑
     * @author yjy
     * 2018-07-25 10:28
     */
    public class SerializerTest {
    
        public static void main(String[] args) throws IOException {
    
            Entity entity = new Entity();
            // 此时两个 CopyOnWriteArrayList 不同
            System.out.println(entity.getList1() == entity.getList2());
    
            // 序列化
            OutputStream outputStream = new FileOutputStream("dubboSerializer");
            GenericObjectOutput objectOutput = new GenericObjectOutput(outputStream);
            objectOutput.writeObject(entity);
            objectOutput.flushBuffer();
    
            // 反序列化
            GenericObjectInput input = new GenericObjectInput(new FileInputStream("dubboSerializer"));
            Entity obj1 = (Entity) input.readObject();
            // 此时两个 CopyOnWriteArrayList 相同????????????????????????
            System.out.println(obj1.getList1() == obj1.getList2());
        }
    
    }
    import java.io.Serializable;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    /**
     * @author yjy
     * 2018-07-25 10:28
     */
    public class Entity implements Serializable {
    
        private static final long serialVersionUID = 187648346954430294L;
    
        private List<Integer> list1 = new CopyOnWriteArrayList<>();
        private List<Integer> list2 = new CopyOnWriteArrayList<>();
    
        public List<Integer> getList1() {
            return list1;
        }
    
        public List<Integer> getList2() {
            return list2;
        }
    }

    这个问题可把我给坑坏了, 现在已经将此问题提交至 github, Issue地址

    解决方案有3种

    1. 避免使用在RPC调用或返回时使用 CopyOnWriteArrayList 对象

    2. 避免使用 dubbo serialization, 改用 hessian 序列化

    3. 将dubbo版本升级为 2.6.x, 并使用默认序列化(hessian)

  • 相关阅读:
    Object.keys方法之详解
    ackbone入门系列(5)路由
    backbone入门系列(4)集合
    backbone入门系列(3)视图
    backbone入门系列(2)模型
    backbone入门系列(1)基本组成部分
    $(document).ready(function(){ })、window.onload=function(){}与(function($){...})(jQuery)的对比和作用
    backbone笔记1,MVC
    用Object.prototype.toString()来检测对象的类型
    Python生成requirements.txt方法
  • 原文地址:https://www.cnblogs.com/imyjy/p/9364921.html
Copyright © 2011-2022 走看看