Java socket/serialization, object won't update
I am writing a little socket based program. I am using a class ModelEvent to pass information through the socket. inside ModelEvent, there's a variable obect of type (Object).
The object itself is a 2D-array with some values.
object[1][2] = 2;
ModelEvent event = new ModelEvent("allo", object);
dispatchEvent(event);
object[2][3] = 2;
ModelEvent event2 = new ModelEvent("you", object);
dispatchEvent(event2);
Let's say that the array object is filled with the value 1. The first event (event) is received by the client, and the data is right. The second event sent though data is not right. Its data is the same as in the first dispatch. the "allo" and "you" is to see if I'm not reading the same event two times and the answer it's not. The string is right, but the object is not, event if it has been updated. I iterate through the array before sending the second event to see if it is updated on the server side, and it is. But on the client side, it still remain the same as in the first dispatch, even if the event itself is changed.
Solution 1:
See ObjectOutputStream.reset
.
Reset will disregard the state of any objects already written to the stream. The state is reset to be the same as a new
ObjectOutputStream
. The current point in the stream is marked as reset so the correspondingObjectInputStream
will be reset at the same point. Objects previously written to the stream will not be refered to as already being in the stream. They will be written to the stream again.
/* prevent using back references */
output.reset();
output.writeObject(...);
Call reset before writing the same object to ensure its updated state is serialized. Otherwise, it will merely use a back reference to the previously written object with its out-dated state.
Or, you could alternatively use ObjectOutputStream.writeUnshared
as follows.
Writes an "unshared" object to the
ObjectOutputStream
. This method is identical towriteObject
, except that it always writes the given object as a new, unique object in the stream (as opposed to a back-reference pointing to a previously serialized instance).Specifically:
An object written via writeUnshared is always serialized in the same manner as a newly appearing object (an object that has not been written to the stream yet), regardless of whether or not the object has been written previously.
If
writeObject
is used to write an object that has been previously written with writeUnshared, the previous writeUnshared operation is treated as if it were a write of a separate object. In other words,ObjectOutputStream
will never generate back-references to object data written by calls towriteUnshared
.While writing an object via
writeUnshared
does not in itself guarantee a unique reference to the object when it is deserialized, it allows a single object to be defined multiple times in a stream, so that multiple calls toreadUnshared
by the receiver will not conflict. Note that the rules described above only apply to the base-level object written withwriteUnshared
, and not to any transitively referenced sub-objects in the object graph to be serialized.
output.writeUnshared(...);
Note it's good practice to couple this with ObjectInputStream.readUnshared
.
Reads an "unshared" object from the
ObjectInputStream
. This method is identical to readObject, except that it prevents subsequent calls toreadObject
andreadUnshared
from returning additional references to the deserialized instance obtained via this call.Specifically:
- If
readUnshared
is called to deserialize a back-reference (the stream representation of an object which has been written previously to the stream), anObjectStreamException
will be thrown- If
readUnshared
returns successfully, then any subsequent attempts to deserialize back-references to the stream handle deserialized byreadUnshared
will cause anObjectStreamException
to be thrown.Deserializing an object via
readUnshared
invalidates the stream handle associated with the returned object. Note that this in itself does not always guarantee that the reference returned byreadUnshared
is unique; the deserialized object may define areadResolve
method which returns an object visible to other parties, or readUnshared may return aClass
object orenum
constant obtainable elsewhere in the stream or through external means. If the deserialized object defines areadResolve
method and the invocation of that method returns an array, thenreadUnshared
returns a shallow clone of that array; this guarantees that the returned array object is unique and cannot be obtained a second time from an invocation ofreadObject
or readUnshared on theObjectInputStream
, even if the underlying data stream has been manipulated.
obj = input.readUnshared();
Solution 2:
I don't see the dispatchEvent code, but from what you wrote I assume the following: you write the same object (only its state changed), this means it will write only the reference twice. you can see in java output stream docs (for performance).
you should use writeUnshared(), which will create a new object on each write
I see reset was suggested, this will get you to the same result, but it has performance impact.