CDV ❯ on-load behavior is not inherited
-
Bug
-
Status: Open
-
2 Major
-
Resolution:
-
-
-
prodmgmt
-
Reporter: hmak
-
March 06, 2009
-
0
-
Watchers: 2
-
March 19, 2010
-
Attachments
Description
on-load behavior associated with a parent is not inherited to a child class [even if the child is instrumented].
Attached is reproduce case where:
- ClassA.main() can run multiple times successfully
- ClassB.main() fails on 2nd, 3rd, etc runs w/ the following exception
[quote] onTCLoad() invoked on [ClassA(true)] Exception in thread “main” java.lang.Exception: transient was not repaired for [ClassB(false)] at ClassA.test(ClassA.java:17) at ClassB.main(ClassB.java:6) [/quote]
Workaround is to define an on-load behavior for every subclass but this does not scale too well in our setup since we allow 3rd parties to subclass our DSO’s.
Comments
Tim Eck 2009-03-06
Howard Mak 2009-03-06
Hmm, my reproduce case was too simple. :)
ClassA+ covers ClassB, but unfortunately this won’t scale if I have ClassC extends ClassB as ClassA+ only covers direct subclasses, not descendants that are twice removed (e.g., ClassC)
Howard Mak 2009-03-09
Okay, so I was wrong. ClassA+ will cover even descendants of its child. I was mislead by the Terracotta Eclipse plugin (re: https://jira.terracotta.org/jira/browse/CDV-1179).
Nonetheless, it’s still weird that if I specify an on-load behavior for ClassC, it will overwrite [rather than be added to] the the on-load behavior for its parent.
Howard Mak 2009-03-09
Can we have a new feature where on-load behavior can be specified as cumulative instead of overwrite?
Fiona OShea 2009-03-10
Feature request on last comment.
Fiona OShea 2009-03-10
It helps us to prioritize requests if we have real world use cases. Can you explain yours to help us with that? thanks
Howard Mak 2009-03-10
We want 3rd parties to extend our classes [which are DSO’s]. They can too easily accidentally damage the restoration of transient fields in our base classes.
For example, given:
[quote] @InstrumentedClass @HonorTransient public class Us { private transient boolean m_f = true;
public void restoreTransient() \{
m\_f = true;
\}
\} [/quote]
we want 3rd parties to be able to write
[quote] @InstrumentedClass @HonorTransient public class Them1 extends Us { }
@InstrumentedClass
@HonorTransient
public class Them2 extends Us \{
private transient boolean m\_f2 = true;
public void restoreTransient() \{
super.restoreTransient();
m\_f2 = true;
\}
\} [/quote]
The problem above is that in the current Terracotta implementation, restoreTransient() will *not* be invoked for Them1 or Them2. The workaround is to do omit @InstrumentedClass + @HonorTransient annotations. i.e., code as
[quote] public interface InheritedTcDso { public void restoreTransient(); }
public class Us \{
private transient boolean m\_f = true;
public void restoreTransient() \{
m\_f = true;
\}
\}
public class Them1 extends Us \{
\}
public class Them2 extends Us \{
private transient boolean m\_f2 = true;
public void restoreTransient() \{
super.restoreTransient();
m\_f2 = true;
\}
\} [/quote]
and tc-config.xml as
[quote]
[/quote]
This is the approach illustrated in the reproduce case for CDV-1179.
There are two problems w/ this workaround:
- If the 3rd party includes @InstrumentedClass + @HonorTransient, the original problem (no transient restore) reappears
- We avoid the refactor-robustness of tim-annotations
- We need to be extra-careful mixing tim-annotations w/ our own tc-config.xml
I didn’t try it yet, but I think if you remove the include for ClassB and change the other one to ClassA+ it should do what you want (that pattern will match classA and all subtypes).