如何从Hazelcast的Imap中检索序列化对象?

时间:2015-03-20 10:45:38

标签: java serialization deserialization hazelcast

以下代码用于将kryo序列化对象放入Hazelcast的Imap实例中,然后进行检索。在检索对象时,它会抛出一个名为:

的错误

com.hazelcast.nio.serialization.HazelcastSerializationException:com.esotericsoftware.kryo.KryoException:java.io.EOFException:ZLIB输入流的意外结束

以下代码如下。在此先感谢!!

包hazelcast2;

import java.util.Scanner;

import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.SerializerConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.ISet;


public class zlibtry {
    public static Config config;
    public static ClientConfig cfg;
    public static HazelcastInstance hz;
    public static IMap<String,MyDataObject> mapItemCount; 

    public static void main(String[] args) throws Exception{
//      Scanner obj = new Scanner(System.in);
        config= new Config();

        config.setProperty("hazelcast.elastic.memory.enabled" , "true");
        config.setProperty("hazelcast.elastic.memory.total.size", "60G");
        config.setProperty("hazelcast.elastic.memory.chunk.size","2");
        MapConfig mapConfig = new MapConfig();
        mapConfig.setInMemoryFormat( InMemoryFormat.OBJECT );
        //config.getNetworkConfig().setPort(5701);
        //config.getNetworkConfig().setPublicAddress("127.0.0.1"); 
        config.setProperty("address","127.0.0.1");

        SerializerConfig productSerializer = new SerializerConfig()
         .setTypeClass(MyDataObject.class).setImplementation(new ProductKryoSerializer(true));
        config.getSerializationConfig().addSerializerConfig(productSerializer);

        hz=Hazelcast.newHazelcastInstance(config);

         mapItemCount=hz.getMap("objectMap");

         MyDataObject obj = new MyDataObject();

         ISet<Integer> iset = hz.getSet("zlibset2");
         iset.add(1);

         obj.setMyList(iset);

         mapItemCount.put("1", obj);

         System.out.println(mapItemCount.get("1").getMyList().toString());





    }   
}

以下代码适用于productKyroSerializer

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;

public class ProductKryoSerializer implements StreamSerializer {
    private final boolean compress;

    private static final ThreadLocal<Kryo> kryoThreadLocal 
           = new ThreadLocal<Kryo>() {

        @Override
        protected Kryo initialValue() {
            Kryo kryo = new Kryo();
            kryo.register(MyDataObject.class);
            return kryo;
        }
    };

    public ProductKryoSerializer(boolean compress) {
        this.compress = compress;
    }

    public int getTypeId() {
        return 2;
    }

    public void write(ObjectDataOutput objectDataOutput, MyDataObject product) 
           throws IOException {
        Kryo kryo = kryoThreadLocal.get();

        if (compress) {
            ByteArrayOutputStream byteArrayOutputStream = 
                new ByteArrayOutputStream(16384);
            DeflaterOutputStream deflaterOutputStream = 
                new DeflaterOutputStream(byteArrayOutputStream);
            Output output = new Output(deflaterOutputStream);
            kryo.writeObject(output, product);
            output.close();

            byte[] bytes = byteArrayOutputStream.toByteArray();
            objectDataOutput.write(bytes);
        } else {
            Output output = new Output((OutputStream) objectDataOutput);
            kryo.writeObject(output, product);
            output.flush();
        }
    }

    public MyDataObject read(ObjectDataInput objectDataInput) 
           throws IOException {
        InputStream in = (InputStream) objectDataInput;
        if (compress) {
            in = new InflaterInputStream(in);
        }
        Input input = new Input(in);
        Kryo kryo = kryoThreadLocal.get();
        return kryo.readObject(input, MyDataObject.class);
    }

    public void destroy() {
    }

//  @Override
//  public Object read(ObjectDataInput arg0) throws IOException {
//      // TODO Auto-generated method stub
//      return null;
//  }

    public void write(ObjectDataOutput arg0, Object arg1) throws IOException {
        // TODO Auto-generated method stub

    }
}

而且,我认为应该有一些适当的方法来在反序列化后检索对象。

你可以看到“objectMap”hazelcast的IMap实例,我已经更新了hazelcast.xml中的一些代码

<map name="objectMap">
    <in-memory-format>OBJECT</in-memory-format>
</map>

<map name="cachedMap">
    <in-memory-format>CACHED</in-memory-format>
</map>

<map name="binaryMap">
    <in-memory-format>BINARY</in-memory-format>
</map>

,myDataObject的代码是

import com.hazelcast.core.IList;
import com.hazelcast.core.ISet;

public class MyDataObject {
ISet<Integer> myList;

public ISet<Integer> getMyList() {
    return myList;
}

public void setMyList(ISet<Integer> myList) {
    this.myList = myList;
}

}

1 个答案:

答案 0 :(得分:2)

ISet不可序列化,不能直接序列化为类内的字段。请参阅以下代码段以获取可能的解决方案。

public class MyDataObject
    implements KryoSerializable, HazelcastInstanceAware {

  private ISet<Integer> myList;
  private String myListName;

  public ISet<Integer> getMyList() {
    return myList;
  }

  public void setMyList(ISet<Integer> myList) {
    this.myList = myList;
    this.myListName = myList.getName();
  }

  public void write (Kryo kryo, Output output) {
    output.writeString(myListName);
  }

  public void read (Kryo kryo, Input input) {
    this.myListName = input.readString();
  }

  public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
    this.myList = hazelcastInstance.getSet(myListName);
  }
}

我想这应该有用(至少有点;-))只是在浏览器中写的。