[Logo] Terracotta Discussion Forums
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
Using SerializationUtils.clone  XML
Forum Index -> General
Author Message
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

When I try to clone a "complex" object (has Lists and custom classes) pulled from cache (ConcurrentHashMap or EhCache) using SerializationUtils.clone, the cloned object does not equal the original object retrieved from cache. I have confirmed that the original object has all of the expected values. It's just the cloned object that is not correct.

When I run SerializationUtils.clone without TC, it clones correctly.

Any thoughts?

Thanks,

Darin Pope
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

Sorry Darin, I don't quite get it. Can you be more specific about what doesn't work correctly? Maybe just some pseudo code to illustrate the problem?

One thing I can think of to check - are you performing the clone under a TC (read) lock?
[WWW]
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

Another thing to try is the apache commons tim.
[WWW]
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

Are you talking about tim-collections?
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

Nevermind about apache commons - I looked through it it does not help with SerializationUtils.

I think what you need to do is change:

Code:
 MyObject clone = (MyObject) SerializationUtils.clone(cache.get(theKey));
 


to:

Code:
 MyObject myObject = (MyObject) cache.get(theKey));
 MyObject clone;
 synchronized (myObject) {
   clone = (MyObject) SerializationUtils.clone(myObject);
 }
 


and add to your tc-config.xml a read lock to cover the method were this code is running:

Code:
 <locks>
   <autolock>
      <method-expression>* com.mycompany.MyBusinessLogic.theMethod(..)</method-expression>
       <lock-level>read</lock-level>
    </autolock>
  </locks>
 
[WWW]
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

I changed the code and added the autolock as you noted but there is no difference; everything works fine standalone, but does not work once instrumented by TC.

Any other ideas?

Darin
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

ok, the last statement was partially true. It appears once the cached value is really faulted into the L1, ie any visit to an L1 after the first visit, the clone works. Here's a step by step test I did:

Code:
 start worker1 and worker2 (empty TC data store)
 worker1 - initial object creation and put to cache; clone of original object succeeds
 close browser
 worker2 - clone fails
 close browser
 worker1 - clone succeeds
 close browser
 worker2 - clone succeeds
 close browser
 worker1 - clone succeeds
 close browser
 worker2 - clone succeeds
 close browser
 stop and start worker1 and worker2 without deleting TC data store
 worker1 - clone fails
 close browser
 worker2 - clone fails
 close browser
 worker1 - clone succeeds
 close browser
 worker2 - clone succeeds
 close browser
 worker1 - clone succeeds
 close browser
 worker2 - clone succeeds
 close browser
 


When I look at the original object during a clone fail step, the original object is populated correctly, but the clone during that step fails.

Maybe this gives a little more info.

Darin
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

Just did a little more testing. I removed the synchronize block and tc-config changes previously recommended and I had the exactly same results as listed above.

Sigh...

So, I think the issue is when the object is first faulted into a L1 from L2, it cannot be cloned even though the object is fully hydrated. However, upon subsequent clone attempts, the clone works fine.

Hopefully this helps.

Darin

tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

for sure it's this gotcha: http://www.terracotta.org/confluence/display/docs1/Gotchas#Gotchas-UninstrumentedAccessGotcha

so we need to instrument SerializationUtils. A naive attempt to do so would be to add it to your instrumented-classes section:

Code:
 <instrumented-classes>
   <include>
     <class-expression>org.apache.commons.lang.SerializationUtils</class-expression>
   </include>
 </instrumented-classes>
 


which might just work - if it doesn't we'll need to see what problem you run into.
[WWW]
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

you don't have to try that doesn't work I reproduced your case here:

http://jira.terracotta.org/jira/browse/CDV-736

[WWW]
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline



ok, I'll start working plan B. I just have to figure out what that plan is...

Thanks

Darin
orion

jedi

Joined: 06/12/2007 14:43:27
Messages: 106
Offline

Would adding it to the boot jar help?

Want to post to this forum? Please join the Terracotta community: Sign up
[WWW]
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

No, I tried that.
[WWW]
dpope

master

Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline

I based my workaround on the following:

http://weblog.dangertree.net/2007/07/05/implementing-a-deep-clone-using-copy-constructors-in-java/

It may not be the best way, but it worked for me.

If anyone else runs into this issue, when you start writing your unit tests (you are doing that right?), start at the bottom of the object tree and work your way back up to the top. That way you know that all of your child objects are correctly deep copying.

Also, in the unit test, do 2 assertions:

Code:
 assertEquals(original,clone);
 assertNotSame(original,clone);
 


That way you make sure that not only the 2 objects are equal, but they are also not the same.
 
Forum Index -> General
Go to:   
Powered by JForum 2.1.7 © JForum Team