简体   繁体   中英

How to debug a Java serialization fault?

I was studying Java Serialization for the first time which said that it could save the Object's 'state'.

So I tried to make a simple Java console game which would create a new 'player' and set its default IQ to 80. And whenever they ran the game (ie run the main function) they will find that their IQ has increased by 1 from the previous time.

Here is my code:

IQIncreaser.java

package IQIcreaserGame;

import java.io.Serializable;

public class IQIncreaser implements Serializable {
    private int iq;



    public int getIq() {
        return iq;
    }

    public void setIq(int iq) {
        this.iq = iq;
    }

    @Override
    public String toString() {
        return "Your IQ is now: " + iq;
    }
}

Main.java

package IQIcreaserGame;

import java.io.*;

public class Main {

    public static void main(String[] args) {
        IQIncreaser bakra = new IQIncreaser();
        bakra.setIq(80);

        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/saveIQ.ser"));
            oos.writeObject(bakra);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Welcome to the IQ increaser!!!");
        System.out.println("Whenver you run this game your IQ will increase by 1!!");
        System.out.println("Just check it out");


        System.out.println("Your IQ at beginning was " +bakra.getIq() + ", come back for more");

        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/saveIQ.ser"));
            IQIncreaser restoredAndIncreased = (IQIncreaser) ois.readObject();

            // Here I am increasing the IQ by one everytime the main runs
            restoredAndIncreased.setIq(restoredAndIncreased.getIq()+1);

            System.out.println("The increased IQ is " + restoredAndIncreased.getIq());
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Now the problem/confusion part :

Whenever I run the game ie everytime I run main() function I thought I would get a expected output in which the player's IQ would increase by 1 because it takes the "previous value" from the .ser saved file and adds 1 to it. Like this the first default value is 80 Then on second run : 81 then on third run: 82 then on fourth run: 83.. and so on

But everytime I am getting 81 as the increased value. Where is the problem and what is the best way to fix this?

update bakra.setIq also

   try {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/saveIQ.ser"));
        IQIncreaser restoredAndIncreased = (IQIncreaser) ois.readObject();

        // Here I am increasing the IQ by one everytime the main runs
        restoredAndIncreased.setIq(restoredAndIncreased.getIq()+1);
        bakra.setIq(restoredAndIncreased.getIq()+1);
        System.out.println("The increased IQ is " + restoredAndIncreased.getIq());
        ois.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

You initially run the writeObject() function and everytime it saves 80 as the value. But when you increment the value from the latter part of the code you don't write it to the file. Just increment, read and ignore.

Event though you write it there it will again replace to 80 because of following code in upper part of main method.

        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/saveIQ.ser"));
            oos.writeObject(bakra);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

Solution

You have to initially set the value 80 and save it to file. Then when ever you run the program just increment the value and save it again. Don't initialize it into 80 again.

 public static void main(String[] args) {
        IQIncreaser bakra = new IQIncreaser();
        bakra.setIq(80);

        try {
            if (!Paths.get("D:/saveIQ.ser").toFile().exists()) {
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/tmp/abc.ser"));
                oos.writeObject(bakra);
                oos.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("Welcome to the IQ increaser!!!");
        System.out.println("Whenver you run this game your IQ will increase by 1!!");
        System.out.println("Just check it out");


        System.out.println("Your IQ at beginning was " + bakra.getIq() + ", come back for more");

        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/saveIQ.ser"));
            IQIncreaser restoredAndIncreased = (IQIncreaser) ois.readObject();

            // Here I am increasing the IQ by one everytime the main runs
            restoredAndIncreased.setIq(restoredAndIncreased.getIq() + 1);

            System.out.println("The increased IQ is " + restoredAndIncreased.getIq());
            ois.close();

            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/saveIQ.ser"));
            oos.writeObject(restoredAndIncreased);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

Please find the complete code below. Basically you need to ensure that you are overwriting the file one it has been created, else, you are restoring the IQ back to 80. Finally ensure your serialize your object back to same filw after incrementing the IQ.

class IQIncreaser implements Serializable{
    int Iq ;

    public int getIq() {
        return Iq;
    }

    public void setIq(int iq) {
        Iq = iq;
    }

}


public class Main {

    public static void main(String[] args) {
        Path path = Paths.get("/home/akshayap/saveIQ.ser");
        //create default file only if it does not exist
        if (Files.notExists(path)) {
        IQIncreaser bakra = new IQIncreaser();
        bakra.setIq(80);

        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/home/akshayap/saveIQ.ser"));
            oos.writeObject(bakra);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        }

        System.out.println("Welcome to the IQ increaser!!!");
        System.out.println("Whenver you run this game your IQ will increase by 1!!");
        System.out.println("Just check it out");


        IQIncreaser restoredAndIncreased=null;

        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/home/akshayap/saveIQ.ser"));
            restoredAndIncreased = (IQIncreaser) ois.readObject();
            System.out.println("Your IQ at beginning was " +restoredAndIncreased.getIq() + ", come back for more");
            // Here I am increasing the IQ by one everytime the main runs
            restoredAndIncreased.setIq(restoredAndIncreased.getIq()+1);

            System.out.println("The increased IQ is " + restoredAndIncreased.getIq());
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            //serialize the object into the same file post increment
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/home/akshayap/saveIQ.ser"));
            oos.writeObject(restoredAndIncreased);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM