| Author |
Message |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 05:53:13
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 06:52:05
|
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?
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 07:27:10
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
Another thing to try is the apache commons tim.
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 07:37:54
|
dpope
master
Joined: 12/11/2007 10:16:33
Messages: 61
Location: Wesley Chapel, NC
Offline
|
Are you talking about tim-collections?
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 07:42:27
|
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>
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 11:20:04
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 12:00:16
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 13:06:49
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 14:04:12
|
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.
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 14:59:06
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/19/2008 16:24:04
|
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
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/21/2008 08:48:45
|
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 |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/21/2008 10:13:43
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
No, I tried that.
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 04/22/2008 11:09:04
|
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.
|
|
|
 |
|
|