(ObjectInputStream subclass)-->readObject() does not flush the buffer...

i've got a subclass ofObjectInputStream (with a corresponding

subclass ofObjectOutputStream).

objects of these 2 classes utilize theannotateClass <>resolveClass handshake that allows instances

of objects on the sending side to execute on the receiver's side

without the receiver pre-knowing the class definitions. ok.

i already had some great help on this, however, there is a loose end.

on thereceiving-side, sendingString works.

SubClass_ObjectInputStream xois =new SubClass_ObjectInputStream(socket.getInputStream());

String string1 = (String) xois.readObject();

String string2 = (String) xois.readObject();

String string3 = (String) xois.readObject();

.....

string1, string2 and string3 are different.

with the following code everytime i performreadObject() i keep reading the first object sent.

SubClass_ObjectInputStream xois =new SubClass_ObjectInputStream(socket.getInputStream());

MyInterface obj1 = (MyInterface) xois.readObject();

MyInterface obj2 = (MyInterface) xois.readObject();

MyInterface obj3 = (MyInterface) xois.readObject();

.......

obj1, obj2, obj3 are the same object (not clones).

flush() by the sender seems to do nothing.

there must be some mechanism inresolveClass() that

effects buffer flushing?

String objects should not call theresolveClass() which i overrode, whileMyClass objects must.

thanks.

Message was edited by:

dew2hiroo

[1692 byte] By [dew2hirooa] at [2007-11-27 1:32:17]
# 1

> String objects should not call the resolveClass() which i overrode

Why not? Where does it say that?

You need to make sure not to resolve JDK classes in your override. If MyData is the only class you want to resolve, add a readResolve() method to that class instead if you can.

ejpa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 2

> > String objects should not call the

> resolveClass() which i overrode

>

> Why not? Where does it say that?

an experiment confirms the de-serialization mechanism does not invoke resolveClass() for java.lang.String.

for java.lang.String the sender does not invoke annotateClass().

for dw.redshoes.MyClass the sender does invoke annoteClass().

so, this issue seems to be on the sending end?

resolveClass() will not be called unless annotateClass() is called by the sender.?

now, how does the sender know that java.lang.String is already loaded in the receivers jvm? and how does it know dw.redshoes.MyClass is not ?

is it just are these educated guesses?

> If MyData is the only class you want

> to resolve, add a readResolve() method to that class

> instead if you can.

i have a small sized library of classes bundled into one jar file.

Message was edited by:

dew2hiroo

Message was edited by:

dew2hiroo

dew2hirooa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 3
> resolveClass() will not be called unless annotateClass() is called by the sender.?I now don't know what relevance the whole question of resolveClass() actually has.Were obj1/2/3 different objects when you sent them? or the same object modified between writeObject()
ejpa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 4

> So were obj1/2/3 different objects when you sent

> them? or the same object modified between

> writeObject() calls?

on the write-end:

XobjectOutputStream xoos = new XobjectOutputStream(sok.getOutputStream());

MyClass obj = new MyClass();

obj.setValue("ABC");

xoos.writeObject(obj);

obj.setValue("LMN");

xoos.writeObject(obj);

obj.setValue("XYZ");

xoos.writeObject(obj);

and then on the receiving end:

XobjectInputStream xois = new XobjectInputStream(sok.getInputStream());

MyInterface x1 = (MyInterface) xois.readObject();

x1.printValue();

MyInterface x2 = (MyInterface) xois.readObject();

x2.printValue();

MyInterface x3 = (MyInterface) xois.readObject();

x3.printValue();

x1, x2, x3 all point to the first object sent. its like the "ABC" valued object is always in the front of the read buffer.

of course, send-side i only create 1 object, but serializing is just like doing a deep clone, so its really 3 objects in the buffer.

this is the results of above code printed to terminal:

ABC

ABC

ABC

and then note:

x2.setValue("RRR");

x1.printValue();

x2.printValue();

x3.printValue();

prints:

RRR

RRR

RRR

dew2hirooa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 5
I thought so. In this case serialization i s behaving as specified, i.e. it is conserving the object graph by sending a handle to the same object rather than a new object. If you don't want this behaviour, investigate ObjectOutputStream.reset() or ObjectOutpuStream.wruiteUnshared().
ejpa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 6

[NOTE]:

you know what? i bet its my implementation of

annotateClass().

its not exactly written 100% to specs.

i've had a lot of trouble writing this correctly.

can you clear this up:

the API says "This method may make free use of the ObjectOutputStream to save any representation of the class is deems suitable (fir example, the bytes if the class file)."

is this going to be like:

protected coid annotateClass(Class myClass) {

InputStream f = new FileInputStream(?);

byte[] b = new byte[1];

while(f.read(b) != -1) {

this.write(b);

}

}

i am sure i can use myClass to find the appropriate class file?

right?

[sorry that our posts crossed. i will look at your recommendataion tomorrow thanks]

Message was edited by:

dew2hiroo

dew2hirooa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 7

indeed, the solution is ObjectOutputStream.reset().

XobjectOutputStream xoos = new XobjectOutputStream(sok.getOutputStream);

MyClass obj = new MyClass();

obj.setValue("ABC");

xoos.writeObject(obj);

xoos.reset();

obj.setValue("DEF");

xoos.writeObject(obj);

xoos.reset();

......

a remaining mystery is how does ObjectOutputStream know when to invoke an overridden annotateClass()... in that it does not for "java.lang.String, and does for dw.redshoes.MyClass..

note:

(1) annotateClass() is called before resolveClass(), so its not like the receiver calls back to the sender.

(2) both annotateClass() and resolveClass() are invoked twice. so there is some kind of tcp-like handshaking going on..?

in any event, i consider this issue closed. thanks ejp.

dew2hirooa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 8
There's no handshake and no real mystery. String is handled specially in ObjectOutputStream.writeObject and ObjectInputStream.readObject().
ejpa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...
# 9

> There's no handshake and no real mystery. String is

> handled specially in ObjectOutputStream.writeObject

> and ObjectInputStream.readObject().

java.lang.Integer does in fact fire annotateClass().

i guess i won't be using java.lang.String as a test class

anymore.

Message was edited by:

dew2hiroo

dew2hirooa at 2007-7-12 0:36:34 > top of Java-index,Core,Core APIs...