3

Update: OK so I've grayed out parts of code and found what was causing the problem. I've added here 3 lines of code with the comment "this is the added code that causes the problem".

But I still don't understand why it affects the result.

I am working on a client-server application that sends data objects via ObjectOutputStream and ObjectInputStream.

I noticed something strange that made me think I might not fully understand object referencing.

On the client side I have a method that creates and returns a User object:

private static User createNewUser()
{
    User newUser = new User();

    newUser.name = "Jim";
    newUser.phone = "054-6885644";
    ..

    return newUser;
}

I create a User object using this method, change one of its properties and send it to the server:

User user = createNewUser();

out.writeObject(user); // this is the added code that causes the problem
out.flush(); // this is the added code that causes the problem

system.out.println("old phone number: " + user.phone); // this prints out 054-6885644
user.phone = "052-9008801";
system.out.println("new phone number: " + user.phone); // this prints out 052-9008801

out.writeObject(user);
out.flush();

On the server side I read the object:

User user = (User) in.readObject(); // this is the added code that causes the problem

User newProfile = (User) in.readObject();
System.out.println("phone number: " + newProfile.phone); // this prints out 054-6885644 (why??)

So, as you can see, before I stream the object, the propery was updated. But after the server deserializes it, it gets the original property value. Why is that?

By the way, I tried cloning the object before streaming it (creating an entirely different object and just copying the fields) and it worked - the propery value did not revert.

So why is this happening? Why does the change to the referenced object's property not saved after streaming?

Vince
  • 14,470
  • 7
  • 39
  • 84
Elyakim Levi
  • 360
  • 4
  • 16
  • I replicated this on my system, using 2 different projects, and the server printed out the new number. Please create a [MCVE](http://stackoverflow.com/help/mcve) that produces the same problem, to ensure it's not a problem with other code you might be writing. – Vince Sep 24 '14 at 15:00
  • @VinceEmigh, thank you for your ecomment. I've added the 3 lines of code that replicate the problem. – Elyakim Levi Sep 25 '14 at 10:55
  • Objects sent through the stream are cached. When you send the object a second time, I believe the OOS is using the cached value instead of the object with the new phone value. Try calling `out.reset()` before sending the object a second time. If this works, let me know and ill put it as an answer – Vince Sep 25 '14 at 15:08
  • @VinceEmigh, this indeed solved the problem. thank you! – Elyakim Levi Sep 25 '14 at 16:05

1 Answers1

1

When you output an object using writeObject(Object), the instance will be serialized (as expected). The problem is, the serialized version will be cached, and any time you attempt to write that same instance a second time, the cached version of the serialized instance is referenced.

To avoid this, you can either call reset() after calling writeObject(Object), or you could use writeUnshared(Object)

Vince
  • 14,470
  • 7
  • 39
  • 84