0

In a fairly simple program I wrote, I am saving an object (a game which contains a few other objects) using ObjectOutputStream. My first question is, when I remove "implements Serializable" from any of my classes, a NotSerializableException is NOT thrown. Why not? They are all extending Serializable classes, but shouldn't they themselves have to be Serializable as well?

Another problem I have, which may be related, is that when I read the object back in, I get a java.io.EOFException.

I don't understand why any of these two things are happening. I use the same exact file name for both reading and writing. Why is it hitting the end of the file before it's done?

Here's the writing code:

public void actionPerformed(ActionEvent event)
            {
                try
                {
                    saver.writeObject(game);
                    saver.close();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }

                dispose();
            }

And here's the reading code:

File file = new File("savedgame.dat");
    if (file.exists())
    {
        try
        {
            loader = new ObjectInputStream(new FileInputStream(file));
            game = (GameBoard) loader.readObject();
            loader.close();
        }
        catch (EOFException ex)
        {
            ex.printStackTrace();
        }
    }
    else
    {
        game = new GameBoard();
    }

The exception is being thrown on the game = (GameBoard) loader.readObject(); line.

Here's the stack trace:

java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)

If it helps, I'm using many swing objects, but from my research, I'm pretty sure they're all serializable.

Thanks for the help!

yts
  • 1,890
  • 1
  • 14
  • 24
  • Can you show `readObject` and `writeObject` of `GameBoard`? – tcb Dec 20 '12 at 01:27
  • @tcb I didn't override them. I have no idea how to do that. Would that help me serialize objects not referenced by instance variables? (see my comments on Thilo's answer) – yts Dec 20 '12 at 01:34
  • Do you have a custom `readObject` method defined on the class you are trying to deserialize? – Perception Dec 20 '12 at 01:57
  • @Perception no, I didn't think I had to do that, and I don't know how to either. I don't think my idea of serializing the entire mastermind game is going to work, because from what I understand now, that would require every single object used in my classes to be stored as instance variable. I mean, if I add a layout manager to a JPanel, that's not going to be serialized :/ – yts Dec 20 '12 at 02:03
  • @yts - actually, its not required for you to have a custom `readMethod`. But if you had one I would have asked you to include it in your question, as those can be a source of errors. Next question, how soon after writing the file data out do you try and read it back in? – Perception Dec 20 '12 at 02:10
  • @Perception well, after the file is written, the program closes (the dispose method of the only frame is called). Next time I open the program (which can vary), the JFrame tries reading the JPanel which contains the entire game. – yts Dec 20 '12 at 02:14

2 Answers2

1

They are all extending Serializable classes, but shouldn't they themselves have to be Serializable as well?

No. Serializable is a normal interface in Java, so you inherit it from superclasses, no need to declare it again. You are automatically considered serializable if you extend a serializable class. This is arguably a bit of a design problem in Java.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • As for your IOException, can you verify that the file is not empty? – Thilo Dec 20 '12 at 01:09
  • Is 4 bytes too small? Come to think of it, there are 2 images which should be being written, each of which are 10kb... It's being "modified" according to Windows every time my program writes the object. Does serialization only save objects referenced by instance variables, or once I add something to a JFrame is that essentially what's happening? – yts Dec 20 '12 at 01:14
  • 4 bytes is too small for a serialized object. – Thilo Dec 20 '12 at 01:15
  • yeah, thought so. So why isn't it saving the game object (a JFrame with a bunch of JPanels, JLabels etc)? – yts Dec 20 '12 at 01:17
  • I unserialized twp action listeners, and only the one which was referenced by an instance variable gave me a notserializableexception.. Does that mean that I have to have everything I want serialized referenced by instance variables? – yts Dec 20 '12 at 01:28
  • I referenced another JPanel (inside the GameBoard class) with an instance variable, and now the file is 100kb. I guess that (inconveniently) answers my question. – yts Dec 20 '12 at 01:32
  • How is the other listener referenced? But yes, when you serialize an object, it serializes the state of the object (i.e. its fields). Nothing else. – Thilo Dec 20 '12 at 01:33
  • it's being created and added to the button inside a method. the JButton method is being called like this. JPanel buttonPanel = new JPanel(); buttonPanel.add(createGuessButton()); I assumed that everything is being stored in instance variables in the parent class somewhere... – yts Dec 20 '12 at 01:40
1

My first question is, when I remove "implements Serializable" from any of my classes, a NotSerializableException is NOT thrown. Why not? They are all extending Serializable classes, but shouldn't they themselves have to be Serializable as well?

If the base class is Serializable, then derived class is also Serializable. This means you don't need to explicitly specify that your class implements Serializable.

tcb
  • 2,745
  • 21
  • 20
  • Thanks, Thilo explained that to me. (no sarcasm intended!) My second question is what's really bothering me now :( – yts Dec 20 '12 at 01:24