Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: load an object saved on hard disk after refactoring => "class not found" exception :/

I'm developping an application in java that regulary saves objects onto the hard disk using this simple method:

public void save(String filename)
{
    try
    {
        FileOutputStream fos = new FileOutputStream(filename);
        GZIPOutputStream gzos = new GZIPOutputStream(fos);
        ObjectOutputStream out = new ObjectOutputStream(gzos);
        out.writeObject(this);
        out.flush();
        out.close();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

}

The object is an instance of sebbot.learning.DirectPolicySearch class.

The problem is, after some refactoring, the learning package was renamed to 'ballcapture'. Now, when I try to load a saved file, I get the following exception:

java.lang.ClassNotFoundException: sebbot.learning.DirectPolicySearch

The method I use to load the file is:

public static synchronized DirectPolicySearch load(String filename)
{
    DirectPolicySearch dps = null;
    try
    {
        FileInputStream fis = new FileInputStream(filename);
        GZIPInputStream gzis = new GZIPInputStream(fis);
        ObjectInputStream in = new ObjectInputStream(gzis);
        dps = (DirectPolicySearch) in.readObject();
        in.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    System.out.println(dps);

    return dps;
}

Can anyone help me with this ? Thanks a lot.

like image 327
Seb_Lz Avatar asked May 12 '10 11:05

Seb_Lz


2 Answers

Class name changes (which includes package name changes) are the guaranteed way to break the serialization mechanism; it's simply not designed to work with classes that change names.

Pretty much the only thing you can do is to undo the refactoring to get the originally named class, then get the current version into the same workspace, use the original class to deserialize, programmatically copy its contents into an instance of the refactored class and then serialize that.

If you want to be safe from that kind of hassle, consider using a more robust and flexible serialization method like XStream.

like image 197
Michael Borgwardt Avatar answered Nov 06 '22 13:11

Michael Borgwardt


Your example demonstrates why serialization is not suitable for long-term storage of data: you have no (real) control over the file format, and serialized files are very tightly tied to your source code - if you change your source code, you can't read previously serialized files in anymore.

Applications where serialization is useful is when using RMI to send objects over a network connection, or for short-term temporary storage of data (for example for a cache on disk).

For long-term storage of data, use something else, such as XML as Michael suggests or some other (standard) file format.

like image 30
Jesper Avatar answered Nov 06 '22 12:11

Jesper