Как сериализовать мультикарты с помощью Kryo?

Проблема

Я пытаюсь сериализовать LinkedHashMultimap< /a> с использованием библиотеки сериализации Kryo, но после десериализации я получаю 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. Из документации Kryo видно, что он очень надежен при сериализации произвольных объектов Java. Объекты

  • не нужно реализовывать Serializable,
  • не нужны конструкторы без аргументов для десериализации и
  • Мне даже не нужно ничего знать о структуре объекта до сериализации.

person mchen    schedule 04.01.2015    source источник


Ответы (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]}
person senleft    schedule 24.03.2015