WildBamaBoy
WildBamaBoy

Reputation: 2783

Java - Deserialization InvalidClassException (No valid constructor)

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

Answers (3)

udalmik
udalmik

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

izilotti
izilotti

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

Frank Thomas
Frank Thomas

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

Related Questions