Reputation: 191
I have an object passed from an API call. Now I tried to send this object using ObjectOutputStream, but the class does not implement Serializable.
I can't edit the class to make it implement Serializable, since that API and class is not written by me. How do I make my object serializable?
Upvotes: 1
Views: 3239
Reputation: 28084
You have to extend the ObjectOutputStream, and have to write a custom writeObjectOverride() function. This has to serialize a ReplacementClass. Then any ObjectInputStream can read your unserializable class.
Works somehow like this:
public class MyObjectOutputStream extends ObjectOutputStream {
public void writeObjectReplace(Object o) {
if( o instanceof MyUnserializableClass ) {
o = new ReplacementClass(o);
}
super.writeObjectReplace(o);
}
}
public class ReplacementClass implements Serializable {
Object o;
public ReplacementClass(Object o) {
this.o = o;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
...writeObjectToStreamWithMethodsIn stream....
}
public Object readReplace(ObjectInputStream stream) {
...createOriginalObjectWithDataFromStream...
}
}
This has the advantage that the unserializable object can appear anywhere in the object graph you want to serialize.
Upvotes: 3
Reputation: 262724
You need to make a wrapper class that implements Serialization for the external class.
That does not make the original class serializable, but you can send the wrapper instance over the wire instead.
class MyWrapper implements Serializable{
private transient TheClass wrapped;
MyWrapper(TheClass wrapped){
this.wrapped = wrapped;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.writeObject(wrapped.getA());
stream.writeObject(wrapped.getB());
}
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
wrapped = new TheClass();
wrapped.setA(stream.readObject());
wrapped.setB(stream.readObject());
}
This depends on you being able to reconstruct the instance using its public setters, getters, and constructors.
If the original instance supports other forms of serialization (XML, ASN1, whatever), you can use that in your wrapper, too.
Upvotes: 2