Sharath
Sharath

Reputation: 407

Does kryo serialization work on non serializable class and class have non serializable attributes?

I'm trying to use Kryo library to convert any given object to byteArray and store in a data store or queue for later use. But is it possible to serialize any given object or only object implementing serializable interface can be converted.

Upvotes: 4

Views: 1616

Answers (1)

John Donn
John Donn

Reputation: 1868

It is possible to serialize/deserialize a bean with Kryo also if it doesn't implement java.io.Serialiable and/or if its attributes don't implement Serializable (I run the example with Kryo 2.10; there is the limitation that no argument constructors had to be explicitly defined here because non default constructors were present):

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

public class KryoSerializerExample {

    public static void main(String[] args) {
        KryoHelper kryoHelper = new KryoHelper();
        ClassNotImplementingSerializable obj1 = new ClassNotImplementingSerializable(123, 456, "789");
        ClassNotImplementingSerializable obj2 = (ClassNotImplementingSerializable) kryoHelper.fromBytes(kryoHelper.toBytes(obj1));
        if (obj1.equals(obj2)) {
            System.out.println("the object and its clone are equal as expected");
        } else {
            System.out.println("the object and its clone are not equal, something went wrong");
        }
    }

    public static class KryoHelper {

        Kryo kryo;

        public KryoHelper() {
            super();
            kryo=new Kryo();
        }

        public byte[] toBytes(Object obj){
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try (Output output = new Output(baos)) {
                kryo.writeClassAndObject(output, obj);
            }

            byte[] bytes = baos.toByteArray();
            return bytes;
        }

        public Object fromBytes(byte[] bytes){
            Object retrievedObject;
            try (Input input = new Input( new ByteArrayInputStream(bytes))){
                retrievedObject = kryo.readClassAndObject(input);
            }

            return retrievedObject;
        }

    }

    public static class ClassNotImplementingSerializable {
        private int a;
        private ClassNotImplementingSerializable2 b;

        /**
         * no-arg constructor is necessary
         */
        public ClassNotImplementingSerializable() {
        }
        public ClassNotImplementingSerializable(int a, int b, String c) {
            this.a = a;
            this.b = new ClassNotImplementingSerializable2(b,c);
        }
        public int getA() {
            return a;
        }
        public void setA(int a) {
            this.a = a;
        }
        public ClassNotImplementingSerializable2 getB() {
            return b;
        }
        public void setB(ClassNotImplementingSerializable2 b) {
            this.b = b;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + a;
            result = prime * result + ((b == null) ? 0 : b.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ClassNotImplementingSerializable other = (ClassNotImplementingSerializable) obj;
            if (a != other.a)
                return false;
            if (b == null) {
                if (other.b != null)
                    return false;
            } else if (!b.equals(other.b))
                return false;
            return true;
        }



    }

    public static class ClassNotImplementingSerializable2 {
        private int a;
        private String b;

        /**
         * no-arg constructor is necessary
         */
        public ClassNotImplementingSerializable2() {
        }
        public ClassNotImplementingSerializable2(int a, String b) {
            this.a = a;
            this.b = b;
        }
        public int getA() {
            return a;
        }
        public void setA(int a) {
            this.a = a;
        }
        public String getB() {
            return b;
        }
        public void setB(String b) {
            this.b = b;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + a;
            result = prime * result + ((b == null) ? 0 : b.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ClassNotImplementingSerializable2 other = (ClassNotImplementingSerializable2) obj;
            if (a != other.a)
                return false;
            if (b == null) {
                if (other.b != null)
                    return false;
            } else if (!b.equals(other.b))
                return false;
            return true;
        }
    }
}

There can be problems with some specific field types, such as java.sql.Timestamp for example (there is a way around this one though), and of course java.lang.Thread and the likes.

Upvotes: 2

Related Questions