Java partial (de)serialization of objects
Asked Answered
L

3

3

Let's say we have 3 Classes:

class foo { // not a singleton
    String s;
}
class bar {
    foo f;
    int i;
}
class baz {
    foo sameF;
}

Now we create instances

foo onlyFoo = new foo("the only one");
bar theBar = new bar(onlyFoo, 123);
baz theBaz = new baz(onlyFoo);

After that we want to store them serilazed in a file. If we deserialze theBaz, modify onlyFoo and deserialize theBaz to the file again, theBar still contains the original onlyFoo, so there are two different versions of onlyFoo.

What I want instead is that I store theBaz and theBar without onlyFoo, store the three objects separately and once someone deserialize theBaz I want to give him onlyFoo, too. If he deserializes the changed onlyFoo again, theBaz and theBar will have the same modified onlyFoo, so if someone requests an object (for example theBar) he gets the full serialized object with all the referenced objects (onlyFoo) like the normal serialization process would return.

I know that I have to store the objects and keep the references manually and separately because the default serialization cannot handle this problem. What I don't know is how do I partially serialize/deserialize Java objects? I need to separate the primitives and their wrappers from the 'higher' objects and store this objects separately.

Update

  1. I cannot modify the classes.
  2. I don't know all classes. It should work with all serializable objects I maybe never heard about (they may or may not be final)
Levona answered 30/11, 2012 at 17:49 Comment(3)
is the class open for extension? I mean is it final or not?Proconsulate
Updated the question: 'I don't know all classes. It should work with all serializable objects I maybe never heard about.' I see, if they are final it could be big problem, tooLevona
Please consider to accept (check mark) one of the abswersDewberry
D
2

If you want more controll you could overwrite writeObject() and readObject() and serialize yourself.

class bar {
    ...

    private void writeObject(ObjectOutputStream stream) throws IOException {
      // let version 1, later when you need to have versioning. 
      stream.writeInt(version);
      stream.writeInt(i);
      // leave out 
      // stream.writeObject(foo);

    }
}
// read object the analog, see 

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html#861

Dewberry answered 30/11, 2012 at 18:15 Comment(3)
Hm, I cannot modify the classes itself, but I could wrap them into proxies. This proxies would have writeObject overwritten in a way, that they serialize the object they are made for instead of themselfs. Then I simply serialize the proxy. They need to use reflection for that, but the problem I see is that it should work with all serializable objects even if I never heard about them.Levona
I marked this as the correct answer, because it helped me a lot. I am creating a working prototype and I will post/link it here when its done.Levona
Totally forget about my prototype: gist.github.com/maklemenz/4515273865853b46fac1Levona
S
1

Mark references you don't want serialized with transient keyword.

Sadi answered 30/11, 2012 at 17:52 Comment(3)
You are right, but I cannot change the definitions of foo, bar or baz. The idea is that it works with all objects that are serializable.Levona
Than you have to set references to null manually. If you want generic solution it can be done made with java.reflectionSadi
Hm, if I get another pointer to the object and set the field to null, I can deserialize the first object later and set the second object to the field after deserialization of the first one.Thanks this should work. Is there also another option? I want that the caller of my method can get the full serialized object, too and I don't want to serialize it directly after deserialization to archive this.Levona
M
0

You can make foo transient as below.

class bar {
    transient foo f;
    int i;
}
Manuel answered 30/11, 2012 at 18:7 Comment(1)
Correctly, but as mentioned in another comment I cannot modify these classes.Levona

© 2022 - 2024 — McMap. All rights reserved.