【问题标题】:How can I serialize a Java class via Hazelcast DataSerializable when it contains generic types?当 Java 类包含泛型类型时,如何通过 Hazelcast DataSerializable 对其进行序列化?
【发布时间】:2016-01-15 19:35:23
【问题描述】:

你能告诉我我在这里做错了什么吗?我真的在为 Hazelcast 实现更高效的序列化程序而苦苦挣扎。我有以下 Java 类:

public class Tuple<X, Y> implements DataSerializable
{ 
    public X x;
    public Y y;

    private Tuple()
    {
    }

    public Tuple(X x, Y y)
    { 
        this.x = x; 
        this.y = y; 
    }

    @Override
    public void readData(ObjectDataInput in)
            throws IOException {
        Instance.log("read data");
        this.x = (X)in.readObject();
        this.y = (Y)in.readObject();
    }

    @Override
    public void writeData(ObjectDataOutput out)
            throws IOException {
        Instance.log("write data");
        out.writeObject(this.x);
        out.writeObject(this.y);
    }

}   

我就是这样使用它的:

HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
IMap<String, Set<Tuple<Integer, Double>>> myMap = Hazelcast.getMap("myMap");

但是,每当我尝试使用此映射时(除了实现 Serializable,该场景都可以正常工作),我会返回此异常:

com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.NotSerializableException: Tuple

我在这里做错了什么?感谢任何想法,谢谢一百万!

更新

尝试了这个建议(感谢 noctarius)我现在有了这个:

public class TupleSetStreamSerializer
        implements StreamSerializer<Set<Tuple>> {

    @Override
    public int getTypeId () {
        return SerializationIdentifiers.TupleSerializationFactoryId;
    }

    @Override
    public void write(ObjectDataOutput out, final Set<Tuple> set )
            throws IOException {
        int size = set == null ? 0 : set.size();
        Instance.log("Serialize set");
        out.writeInt(size);
        if (size>0) {
            Iterator iterator = set.iterator();
            while (iterator.hasNext()) {
                out.writeObject(iterator.next());
            }
        }
    }

    @Override
    public Set<Tuple> read( ObjectDataInput in )
            throws IOException {

        Instance.log("Deserialize set");
        int size = in.readInt();
        Set result = null;
        if (size > 0) {
            result = new HashSet<Tuple>();
            for (int i = 0; i < size; i++) {
                result.add(in.readObject());
            }
        }
        return result;
    }

    @Override
    public void destroy () {
    }
}

还有这个

public class TupleStreamSerializer
        implements StreamSerializer<Tuple> {

    @Override
    public int getTypeId () {
        return SerializationIdentifiers.TupleSerializationFactoryId;
    }

    @Override
    public void write(ObjectDataOutput out, Tuple tup )
            throws IOException {
        out.writeObject(tup.x);
        out.writeObject(tup.y);
    }

    @Override
    public Tuple read( ObjectDataInput in )
        throws IOException {
        Object x = in.readObject();
        Object y = in.readObject();
        return new Tuple(x,y);
    }

    @Override
    public void destroy () {
    }
}

使用这样的配置(尝试评论各种变体和所有)

<hazelcast>
    <serialization>
        <serializers>
            <serializer type-class="Tuple">TupleStreamSerializer</serializer>
            <serializer type-class="Set<Tuple>">TupleSetStreamSerializer</serializer>
        </serializers>
    </serialization>
</hazelcast>

我似乎仍然缺少什么?非常感谢!

【问题讨论】:

    标签: java generics serialization hazelcast


    【解决方案1】:

    您必须为 Set 接口编写一个特殊的 StreamSerializer。每当 Hazelcast 开始序列化一个 Serializable 标记类时,它就会失去序列化控制。有一些解决方法,但它们都不是很好。最好的方法是使用 Serializable 拦截 Set 的序列化并提供自定义序列化器:http://docs.hazelcast.org/docs/3.5/manual/html-single/index.html#streamserializer

    您将在 Hazelcast 核心代码中找到 LinkedList 类型的示例:https://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/java/com/hazelcast/internal/serialization/impl/LinkedListStreamSerializer.java

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多