Reputation: 2783
I'm trying to serialize an object and then deserialize it after sending its data to a client program.
Here's an example of how the object's inheritance works. The object I'm serializing and deserializing is person.
Living -> Animal -> NPC -> Person -> Child
Living, Animal, and NPC do not implement Serializable. I can not change those three classes. Person and Child do implement Serializable. Person and Living are also abstract classes. I can serialize a Person (who is a Child) just fine and send it, but when I attempt to deserialize a Person (who is a Child), I get an InvalidClassException on Child, saying "no valid constructor".
Why is this happening? Must Living, Animal, and NPC all implement Serializable?
Upvotes: 17
Views: 17056
Reputation: 7998
Good explanation is done in answers for following question Deserializing an ArrayList. no valid constructor
Long story short - you need no-arg constructor for first nonserializable super class of your class, NPC
in your case.
If you don't have an access to NPC and it doesn't contain no-arg constructor - then you can add one more 'fake' class to hierarchy which will choose the correct one. E.g.
class SomeClass extends NPC {
// will be called during deserialization
public SomeClass(){
// call custom constructor of NPC
super(null);
}
}
class Person extends SomeClass implements Serializable {
// ..
}
Upvotes: 14
Reputation: 4937
I faced the same issue with Hazelcast's serialization, but solved it without resorting to an intermediary class, by using custom serialization. I added an empty no-arg constructor to the Animal class and implemented the Person class as follows:
class Person extends Animal implements Serializable {
private void writeObject(ObjectOutputStream o) throws IOException {
o.writeObject(this.fieldA);
o.writeObject(this.fieldB);
o.writeObject(this.fieldC);
...
}
private void readObject(ObjectInputStream o) throws IOException, ClassNotFoundException {
this.fieldA = (TypeOfA) o.readObject();
this.fieldB = (TypeOfB) o.readObject();
this.fieldC = (TypeOfC) o.readObject();
...
}
}
Upvotes: 0
Reputation: 2514
per this thread, they do not need to implement Serializable, but they (or at a minimum NPC because its the first non-serializable class in the heirarchy) must contain a 0-parameter constructor. if no constructors are defined in the classes, the implicit constructor is adaquate, but if you have other constructors defined in those classes, you must write an explicit 0-parameter constructor.
Since you cannot control NPC, try creating child of it that defines an explicit 0-param constructor but that does not implement Serializable, and see if that doesn't do it.
Upvotes: 2