Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

readClassAndObject fails when Object has same Class type twice with different generics #213

Closed
amiton opened this issue May 1, 2014 · 2 comments

Comments

@amiton
Copy link
Contributor

amiton commented May 1, 2014

Hi,
I wrote a Serializable class Parent which holds 2 SerializablePair with different generics.
Kryo behaves very strangely and fails to deserialize my class because it assumes that the second SerializablePair is the same generics type as the first one (which is wrong).
Am i doing something wrong or is this a major bug in Kryo?

Full example code:

import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.util.Date;

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

public class KryoMain {

    public static void main(String[] args) {
        //create original Parent object:
        Parent origParent = new Parent();
        origParent.setDateStringPair(new SerializablePair<Date, String>(new Date(), null));

        //commenting out this line makes the test work but it means i can't use same class with different generics?! 
        origParent.setDoubleDoublePair(new SerializablePair<Double, Double>(1.1, 2.2));

        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        //write:
        Output output = new Output(byteOut);
        getKryo().writeClassAndObject(output, origParent);
        output.close();

        //read:
        Parent newParent = null;
        Input input = new Input(byteOut.toByteArray());

        //Kryo Exception is thrown in this line?!
        newParent = (Parent) getKryo().readClassAndObject(input);
    }

    public static Kryo getKryo() {
        final Kryo kryo = new Kryo();
        kryo.setAsmEnabled(true);
        kryo.setDefaultSerializer(CompatibleFieldSerializer.class);

        return kryo;
    }

    public static class SerializablePair<F extends Serializable, S extends Serializable> implements Serializable {
        public F first;
        public S second;

        public SerializablePair() {
            super();
        }

        public SerializablePair(final F first, final S second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public String toString() {
            return "Pair [first=" + first + ", second=" + second + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((first == null) ? 0 : first.hashCode());
            result = prime * result + ((second == null) ? 0 : second.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (!(obj instanceof SerializablePair))
                return false;
            SerializablePair other = (SerializablePair) obj;
            if (first == null) {
                if (other.first != null)
                    return false;
            } else if (!first.equals(other.first))
                return false;
            if (second == null) {
                if (other.second != null)
                    return false;
            } else if (!second.equals(other.second))
                return false;
            return true;
        }
    }

    public static class Parent implements Serializable {
        private static final long serialVersionUID = 1L;

        SerializablePair<Double, Double> doubleDoublePair;
        SerializablePair<Date, String> dateStringPair;

        public Parent() {
            super();
        }

        public SerializablePair<Double, Double> getDoubleDoublePair() {
            return doubleDoublePair;
        }

        public SerializablePair<Date, String> getDateStringPair() {
            return dateStringPair;
        }

        public void setDoubleDoublePair(SerializablePair<Double, Double> doubleDoublePair) {
            this.doubleDoublePair = doubleDoublePair;
        }

        public void setDateStringPair(SerializablePair<Date, String> dateStringPair) {
            this.dateStringPair = dateStringPair;
        }

        @Override
        public String toString() {
            return "Parent [doubleDoublePair=" + doubleDoublePair + ", dateStringPair=" + dateStringPair + "]";
        }
    }
}
@romix romix closed this as completed in 1e9b23f May 1, 2014
@amiton
Copy link
Contributor Author

amiton commented May 4, 2014

Hi,
Thanks for the VERY quick fix :)
It works now.
When can we expect an official release that includes these changes?

Thanks,

@romix
Copy link
Collaborator

romix commented May 4, 2014

Official release is expected very soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants