【问题标题】:How to serialize Multimaps with Kryo?如何用 Kryo 序列化 Multimap?
【发布时间】:2015-03-02 12:17:35
【问题描述】:

问题

我正在尝试使用Kryo Serialization library 序列化LinkedHashMultimap,但在反序列化时得到NullPointerException。最小的工作示例如下:

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.google.common.collect.LinkedHashMultimap;
import java.io.*;

public class SerializationTest {

    private static final String ioFileName = "someIO.bin";

    public static void main(String[] args0) {

        // Create LinkedHashMultimap to serialize
        LinkedHashMultimap<String, Object> outObj = LinkedHashMultimap.create();
        outObj.put("x", 1);
        outObj.put("y", "abc");

        // Try to serialize and deserialize
        Kryo kryo = new Kryo();
        writeObj(kryo, outObj);
        LinkedHashMultimap<String, Object> inObj = (LinkedHashMultimap<String, Object>) readObj(kryo);

        System.out.println(inObj);
    }

    public static Object readObj(Kryo kryo) {
        Object obj = null;
        try {
            Input input = new Input(new FileInputStream(ioFileName));
            obj = kryo.readClassAndObject(input);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return obj;
    }

    public static void writeObj(Kryo kryo, Object obj) {
        try {
            Output output = new Output(new FileOutputStream(ioFileName));
            kryo.writeClassAndObject(output, obj);
            output.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

只要调用kryo.readClassAndObject()(第 30 行)就可以看到问题(在 IntelliJ 14 中调试的屏幕截图):

LinkedHashMultimap 在序列化时被损坏,或者只是被错误地反序列化,导致NullPointerException

调用System.out.println(inObj) 时产生的完整堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
Disconnected from the target VM, address: '127.0.0.1:60310', transport: 'socket'
    at com.google.common.collect.AbstractMapBasedMultimap$AsMap.toString(AbstractMapBasedMultimap.java:1293)
    at com.google.common.collect.AbstractMultimap.toString(AbstractMultimap.java:239)
    at com.google.common.collect.LinkedHashMultimap.toString(LinkedHashMultimap.java:81)
    at java.lang.String.valueOf(String.java:2854)
    at java.io.PrintStream.println(PrintStream.java:821)
    at SerializationTest.main(SerializationTest.java:23)

有人知道如何解决这个问题吗?

动机:

为了帮助远程调试 (Java),能够请求远程服务器将任意对象发送到我的本地计算机进行检查是很有用的。但是,这意味着远程服务器必须能够序列化一个在运行时事先不知道的任意 java 对象。

所以我四处打听,偶然发现了Kryo serialization library。从Kryo's documentation 开始,一个主要特性是它在序列化任意java 对象方面非常健壮。对象

  • 不必实现Serializable
  • 不需要无参数构造函数即可反序列化和
  • 在序列化之前,我什至不需要了解对象的结构。

【问题讨论】:

    标签: java serialization deserialization kryo


    【解决方案1】:

    在进行序列化/反序列化之前尝试下一个(在我的情况下,它适用于 kryo.WriteObject 和 kryo.readObject)

        JavaSerializer serializer = new JavaSerializer();
        kryo.register(LinkedHashMultimap.class, serializer);
    

    工作示例:

    public class SerializationTest {
    
    private static final String ioFileName = "someIO.bin";
    
    public static void main(String[] args0) {
    
        // Create LinkedHashMultimap to serialize
        LinkedHashMultimap<String, Object> outObj = LinkedHashMultimap.create();
        outObj.put("x", 1);
        outObj.put("y", "abc");
    
        // Try to serialize and deserialize
        Kryo kryo = new Kryo();
        kryo.register(LinkedHashMultimap.class, new JavaSerializer());
        writeObj(kryo, outObj);
        LinkedHashMultimap<String, Object> inObj = (LinkedHashMultimap<String, Object>) readObj(kryo);
    
        System.out.println(inObj);
    }
    
    public static Object readObj(Kryo kryo) {
        Object obj = null;
        try {
            Input input = new Input(new FileInputStream(ioFileName));
            obj = kryo.readClassAndObject(input);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return obj;
    }
    
    public static void writeObj(Kryo kryo, Object obj) {
        try {
            Output output = new Output(new FileOutputStream(ioFileName));
            kryo.writeClassAndObject(output, obj);
            output.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    

    }

    输出:

    {x=[1], y=[abc]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      相关资源
      最近更新 更多