I have written my Container<T>
class which backups its T
items in several collections -- primary one is List<T>
, others are various maps with data derived from items, mostly for optimized search.
Class looks like this:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private final Map<...> map1 = Maps.newHashMap();
private final Map<...> map2 = Maps.newHashMap();
}
Standard serialization works like a charm, but maps do not need to be serialized. I tried to set maps as transient
and use readObject()
in this way:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private transient Map<...> map1;
private transient Map<...> map2;
public Container() {
initContainer();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initContainer();
}
private void initContainer() {
map1 = Maps.newHashMap();
map2 = Maps.newHashMap();
// prepare data in maps
for (T item: items) {
map1.put(...);
map2.put(...);
}
}
}
Simple test with ObjectOutputStream.writeObject()
and ObjectInputStream.readObject()
again works. But when I integrate Container
to real application where is this class serialized and deserialized as a part of other complex classes (Wicket Page in fact), strange things happens.
I did some debugging and here are my findings:
- serialization of
Container
with (n) items has done OK - deserialization of
Container
has done OK - deserialization of each
T
item is called only (n-1) times (by counting calls to itsreadObject()
method) - in
containerInit()
hadList<T>
correct (n) number of items, but one of them (that one for which is not called deserialization) is in very strange state - all fields havenull
value - and my code here throws NPE
Questions:
- What state has that strange object after deserialization (it is existing but without
readObject()
call and with null in all fields)? - Maybe deserialization of that strange object is not completed, but I have read that reading objects from
ObjectInputStream
is blocking, so all objects in my list must be in correct state. Or I something overlooked? - Are there any technique/tool/practice for catching things like this?
Thank you.