Jeremy Lee
Jeremy Lee

Reputation: 191

Serialization of Java object created from external API

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

Answers (2)

Daniel
Daniel

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

Thilo
Thilo

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

Related Questions