File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Transitive Object Serialization Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Transitive Object Serialization" Watch "Transitive Object Serialization" New topic
Author

Transitive Object Serialization

Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Hi guys. I'm having a problem with keeping my data persistent.

To give some background, I'm trying to make a text-based adventure game just for practise.

The classes that I'm trying to keep persistent are Room and Exit. Exit's constructor takes two Rooms and an int. The Room class has an Array of Rooms, which is how I've handled moving from room to room in the program.

The problem is that, using Serialization, I've managed to keep my created Rooms and Exits persistent by storing them in an ArrayList each and writing them to a file using ObjectOutputStream and reading them back into the ArrayLists with an ObjectInputStream, but the pointers in the Room class's Array get wiped. Both Room and Exit are Serializable and, by my understandings, that should've maintained any 'transitive'
Objects as well, but that doesn't seem to be the case.

Am I going about persistence in the right way, or is there a better way to be doing thing?

I hope I've made the problem clear enough,

Cheers.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18886
    
    8

Tim Morris wrote:I hope I've made the problem clear enough,


Not really. For example posting your code would demonstrate whether you were expecting objects referred to by static variables to be serialized, for example. You did say

the pointers in the Room class's Array


which suggests that's what you did, but there's nothing like code for clarifying a question about programming.
Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Room Class



Exit class



Those're the classes that I'm trying to serialize by writing an ArrayList of each type to a file with an ObjectOutputStream and reading them back in and storing them again as an ArrayList of each type with an ObjectInputStream.

And here's the Data class with the ArrayLists and the serialization methods



Cheers.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18886
    
    8

Can you show us the code which does the serializing and the deserializing? and also the code which explains that strange "Data" thing?
Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Thanks for helping out.

I've appended the Data class to my previous post. The 'write' methods are supposed to be serializing and the 'read' methods are supposed to be deserializing.

The problem is in the Room class at the top, with the Array of Rooms. What happens is, when an instance of Exit is created it sets a specific index, corresponding to a direction value, of that array to a Room Object. When I deserialize the Room and Exit ArrayLists, those values are not kept persistent and are instead all set back to null again.

I hope that clears up the problem.
Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1509
    
    5

Hi Tim Morris,

I'm not in touch with serialization recently, but this is what I guess:

When you serialize the ArrayList of rooms, it actually dumps the ArrayList to file. However, the ArrayList contains references to objects (and not actual objects). So, when you deserialize it, what you get is a list containing references to Room objects.

Now, it can very well happen that objects referred by those references are garbage collected after serialization and before deserialization. And that can be the reason why you are not getting the data properly.

One solution to this issue is - in your writeObject method, you need to write data of all objects one by one. Further, those objects should be read in readObject method and then put in ArrayList.

I hope this helps.

Correct me if I'm wrong.


Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Cheers Anayonkar!

It works now, but there's another problem...I have no idea WHY it's working.

The Room Array still remains un-filled after deserialization but, for some reason, it's still working when I give in the correct commands. It shouldn't be working with an empty array, yet it is.

Any idea why this is? I feel a bit nervous carrying on coding from this point without understanding this, just in case another problem occurs in the future.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Anayonkar Shivalkar wrote:Hi Tim Morris,

I'm not in touch with serialization recently, but this is what I guess:

When you serialize the ArrayList of rooms, it actually dumps the ArrayList to file. However, the ArrayList contains references to objects (and not actual objects). So, when you deserialize it, what you get is a list containing references to Room objects.

[...snip...]

Correct me if I'm wrong.


No, when you serialize an object that contains references to other serializable objects, the "contained" objects are serialized as well.

Try this, note that it works fine, and then work out the differences between what it does and what you're doing:


HINT: What, exactly does new FileOutputStream(folderFileName); do? (EDIT: I think I mis-read your code, so this is probably not the source of the problem.)
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Tim Morris wrote:Cheers Anayonkar!

It works now, but there's another problem...I have no idea WHY it's working.


Strip down your current code to an SSCCE that demonstrates the problem. Get rid of all the extra junk and leave just enough to show the problem. Then post that code.


The Room Array still remains un-filled after deserialization


I wouldn't call that "working".

but, for some reason, it's still working when I give in the correct commands. It shouldn't be working with an empty array, yet it is.


Meaning what, exactly?
Jelle Klap
Bartender

Joined: Mar 10, 2008
Posts: 1821
    
    7

The Data class you've created maintains two static ArralyLists of Rooms and Exits respectively.
Now static fields aren't included by the serialization process, but that point is moot, because the entire Data class isn't Serializable to begin with.
So when you serialize / deserialize an Exits and Rooms the object graph will be rebuilt properly, meaning Rooms still refer to their associated Exits and such, but the Arraylists will remain empty.
Which is why things "still work" regardless of the ArrayLists being empty.

My guess is you created the Data class as a sort of persistence utility, repsonsible for serialization / deserialization of objects, which isn't a bad thing, but you also made it responsible for keeping track of your world's structure.
That last bit of responsibility would be better suited to a, for instance, World class, which could be Serializable as well.

Edit: ugh, capitalization and apostrophes...


Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Jeff, here's a small example that illustrates the problem in my program. When the MyObject and ObjAsParam are constructed, the Array of MyObjects within MyObject is filled correctly. But when the file has been deserialized, the Array is no longer filled.

That problem hasn't been fixed.

What I mean when I say that the program is working now is that, in my actual program, even though the Array hasn't been re-populated after deserialization, when I need to access data in the (supposedly)
empty Array, it works as if it were non-empty. Effectively working as desired.

Cheers.

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18886
    
    8

All through this thread (at least, since we got code listings) it has been my understanding that it's the m_exitRooms variable which isn't being deserialized correctly.

But now I realize you haven't actually said that. So maybe you're talking about something else. You have just been referring to the problem in vague terms, calling the thing which isn't being deserialized "the array" and things like that. Can we have an accurate description of the problem? Talk about the code.
Tim Morris
Greenhorn

Joined: Mar 31, 2012
Posts: 8

Apologies for my terrible explanation abilities; it's why I try not to ask for help if I can help it!

This is what I suspect, that the m_exitRooms Array isn't deserializing properly.

If you take the latest code that I posted, which was only an illustrative example of what's happening in my code, then the new problem is as follows:

I'm now Serializing MyObject and ObjAsParam objects and THEN I'm deserializing them and storing them into two separate ArrayLists - m_objList, m_objParamList - of the correct type (that step isn't covered in the above code since it shouldn't really have any effect on the program as a whole, by my understanding). So rather than Serializing m_objList and m_objParamList, I'm taking each of the Objects from the m_objList and m_objParamList and Serializing them one by one.

MyObject contains an Array of type MyObject called m_array.

When an instance of ObjAsParam is created, it takes two MyObjects as parameters. The m_array of each of the passed MyObjects will then be set to the other MyObject and the Objects are serialized, signified by these lines:


And the m_array values have been properly assigned, because it correctly references the Object, signified by these lines:



The problem is in deserialization where the variables are assigned after being read in:


The m_array variables in the MyObject classes no longer return a reference and are instead null:


Yet, in my actual program, when m_array (or m_exitRooms) is accessed at this point, it behaves as if it actually DOES contain references.

Hope this clears it up further.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Transitive Object Serialization