aspose file tools*
The moose likes Java in General and the fly likes Incompatibility problems when altering serialized objects Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Incompatibility problems when altering serialized objects" Watch "Incompatibility problems when altering serialized objects" New topic
Author

Incompatibility problems when altering serialized objects

Kari Nordmann
Ranch Hand

Joined: Feb 12, 2007
Posts: 38
I'm working on a hobby project that is alot bigger than my previous work, and the complexity of the program is teaching me alot.
I have now met an issue that I don't see any easy way to pass, and I would like to know how this works in the world of professional programming.

Alittle on my program:
My program has several object classes that make out a core of the program.
One object class is Object_Gear. Object_Gear is dependant on datas from objects of type Object_Stats, Object_DropSpot, Object_Buff and Object_Gem, in addition to normal variables. Object_Stats is an especially crucial class, few things will work properly without it.
All instances of Object_Gear, most instances of Object_Stats and some instances of Object_DropSpot will be created by the user. The user will build up a database, that makes up alot of the point of the program.

Although I have planned alot on my program, I am not entirely sure of all I need from every object class. It is a program made for a complex task with alot of details, and I find it hard to plan out every little thing. The task of the program might also change slightly with time, it is something I can't control. Thus my program has to be compatible with changes in the object classes.

The problem:
Right now I use readobject\writeobject to save and load the database on a *.data file.
Whenever I do a change in any object class, all previously saved instances of that class are incompatible and cant be loaded. The database is lost.
How am I supposed to be able to do changes to an object class and still be able to fit in all instances of the old, now non-existant class?
If I add a variable to one of the classes, how can I tell the program what variables we do have in the file and what has to be filled in, to make it fit?
If I remove a variable in a class, how can I tell the program what variable from the file should not be filled in, and which should?
How is this usually done in larger systems?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19792
    
  20

Originally posted by Kari Nordmann:
Right now I use readobject\writeobject to save and load the database on a *.data file.
Whenever I do a change in any object class, all previously saved instances of that class are incompatible and cant be loaded. The database is lost.
How am I supposed to be able to do changes to an object class and still be able to fit in all instances of the old, now non-existant class?
If I add a variable to one of the classes, how can I tell the program what variables we do have in the file and what has to be filled in, to make it fit?
If I remove a variable in a class, how can I tell the program what variable from the file should not be filled in, and which should?
How is this usually done in larger systems?

First of all, define a special field in your class:

If you omit this, a default value will be used. If you change the class signature (e.g. add or remove fields) a different value will be used.

If you keep this value the same, you will find that there will be no more "incompatible class version" errors.

That alone will already be enough if the fields will remain the same - the same names, types and order. If you change this too, you will need readObject and writeObject. Fortunately, you're already doing that.

Now if you add or remove fields that will be harder. Although there is one quite easy solution - use a Map with the field names as the keys and the field values as the values (boxed if needed). If a different version doesn't care about a field, it can ignore it. If it misses a field, give it a default value.

In code:

As you can see, two different classes with the same name and serialVersionUID, but different fields.

The output (writing first, reading second):

As you can see, field1 and field2 are deserialized just perfectly. field3 is ignored, while field4 gets a default value (null).


Note that it is VERY important that you check for null for all fields, and preferrably the type too.

If you want to keep any ignored values as well, you can also make the Map a private field; you assign it the read value, and only overwrite the values when writing the Object.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Kari Nordmann
Ranch Hand

Joined: Feb 12, 2007
Posts: 38
Ah thanks alot
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Incompatibility problems when altering serialized objects