Search code examples
javaserversocket

Data loss when passing objects via ObjectStream


I am trying to pass an object from the server to the client using ObjectOutputStream . DataObject class:

public class DataObject implements Serializable{
    private byte dataType;
    private Object data;

public DataObject(byte dataType, Serializable data) {
    this.dataType = dataType;
    this.data = data;
}

Player class

public class Player implements Serializable{
    private int mana, health;
    private List<Integer> hand, grave, deck, used;
    private Effect healing, posioned, grievousWound, exhaust, resistance, power;
    private Player enemy;

I sent it away with this code

os = new ObjectOutputStream(server.getOutputStream());
os.writeObject(new DataObject((byte) 8, this.player));
System.out.println(this.player);
// It has printed out exact object

And get it with

DataObject d = (DataObject) is.readObject()
System.out.println(d.getDataType());
System.out.println(d.getData());
System.out.println((Player)d.getData());

It has printed out

8
null

What is the problem I'm having?

I fixed Object to Serializable

private byte dataType;
private Serializable data;

os.writeObject(new DataObject((byte) 8,(Serializable)this.player));

Solution

  • The code shown is okay(ish). The bug lies somewhere else. To demonstrate this I have expanded the original code to make an MRE, other than not reproducing and containing unnecessary detail.

    import java.io.*;
    import java.util.*;
    
    class DataObject implements Serializable{
        private byte dataType;
        private Object data;
        public DataObject(byte dataType, Object data) {
            this.dataType = dataType;
            this.data = data;
        }
        public byte getDataType() { return dataType; }
        public Object getData() { return data; }
    
    }
    class Effect implements Serializable { }
    class Player implements Serializable {
        private int mana, health;
        private List<Integer> hand, grave, deck, used;
        private Effect healing, posioned, grievousWound, exhaust, resistance, power;
        private Player enemy;
    }
    class Code {
        private final Player player = new Player();
    
        public static void main(String[] args) throws Throwable {
            new Code().go();
        }
    
        public void go() throws Throwable {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            try (ObjectOutputStream os = new ObjectOutputStream(out)) {
                os.writeObject(new DataObject((byte) 8, this.player));
                System.out.println(this.player);
            }
            ObjectInputStream is = new ObjectInputStream(
                new ByteArrayInputStream(out.toByteArray())
            );
            DataObject d = (DataObject) is.readObject();
            System.out.println(d.getDataType());
            System.out.println(d.getData());
            System.out.println((Player)d.getData());
        }
    }
    

    This prints:

    Player@4fca772d
    8
    Player@49097b5d
    Player@49097b5d