2

I am trying to write message to a file using serialization.Message consists of two fields- date and TibrvMsg(TibrvMsg is a propriotory message by Tibco and this class is not serializable as per their documentation).So my custom message is:

Message msg = new Message(TibrvMsg msg)

Problem is though i am declaring Message Serializable, i am not able to serialize it as TibrvMsg is not serializable. So i get java.io.NotSerializableException: com.tibco.tibrv.TibrvMsg exception.

kvorobiev
  • 5,012
  • 4
  • 29
  • 35
user420760
  • 43
  • 4

3 Answers3

2

Another approach is to use a serialization proxy. Serialization proxy is a different class altogether than the object being serialized with the logical state of the object. The Object readResolve() method to write a proxy instead of this object and create an object by reading proxy.

Some semi-pseudo code:

class Message implements Serializable {

  private Date dt;
  private TibrvMsg msg;

  private Object writeReplace() {
     return new Proxy(this);
  }

  private static class Proxy implements Serializable {
     private Date dt;
     private Map msgData;

     Proxy(Message msg) {
        this.dt = msg.dt;
        this.msgData = doTransform(msg.msg, "UTF-16");
     }

     private Object readResolve() {
        Message msg = new Message();
        msg.dtd = dt;
        msg.msg = asTibrvMsg(msgData);
        return msg;
     }
  }
}

Additionally override readObject(ObjectInputStream) to throw an InvalidObjectException. The serialization proxy pattern also has certain security advantages over normal serialization. It also has a few disadvantages

naikus
  • 24,302
  • 4
  • 42
  • 43
1

You need to find a way to represent your TibrvMsg as a serializable object (maybe something like this, which transforms it into a Map).

You can then override the following two methods to write this data to the output stream (or read it):

private void writeObject(java.io.ObjectOutputStream out)
     throws IOException{
    out.writeObject(date);
    out.writeObject(doSomethingWithTibrv(tibrv);
}

 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException{
     date = (Date) in.readObject();
     tibrv = readTibrv(in.readObject());
 }
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • Thanks.I am doing exactly the same.But program throws an exception.One option i see is to get various fields from TibrvMsg and attach to Message and then write Message to file. – user420760 Aug 23 '10 at 06:56
  • java.io.NotSerializableException: com.tibco.tibrv.TibrvMsg TibrvMsg contains key value pairs.I will get them and then include as a part of Message before writing it to file. – user420760 Aug 23 '10 at 07:12
  • you should not be getting this exception if your writeObject works properly. – Thilo Aug 23 '10 at 07:18
  • You should always add `defaultReadObject`/`getFields` (read?) and `defaultWriteObject`/`putFields` (write?) to the start of `readObject` and `writeObject`. (And add necessary `transient` or `serialPeristentFields` (spelt correctly).) – Tom Hawtin - tackline Aug 23 '10 at 10:43
0

What do you mean by "this class is not serializable as per their documentation"? Couldent you just extend their class and implement serializable? Its just a marker interface, so...

InsertNickHere
  • 3,616
  • 3
  • 26
  • 23
  • 1
    yes.I can do that.But I was wondering why they didn't privide that.Anyway, i have found that one method getAsBytes() in TibRvMsg class that returns byte array of message and documentation says that this can be used to archive the message. – user420760 Aug 23 '10 at 07:23
  • 1
    If you extend a class and implement `Serializable`, the fields of the base class are not serialisable (for good reason) and the no-arg constructor is used for initialisation instead. – Tom Hawtin - tackline Aug 23 '10 at 10:44