From: twundke <nu...@jb...> - 2005-05-13 06:29:24
|
I have the same problem, and have found out what's going on through much trial and error! The basic problem occurs when you're attempting to instrument a class and its superclass. | public abstract class Base { | private int attribute; | | getAttribute()... | setAttribute()... | } | | | public class Extender extends Base { | private int other; | | getOther()... | setOther()... | } | | | <aop> | <prepare expr="field(* $instanceof{Base}->*)" /> | </aop> | Now, if you attempt to use the class Extender, the JVM will automatically load in Base for you. However, Extender goes through the instumentation phase before Base! This is the root of the problem. org.jboss.aop.instrument.Instrumentor has the following code: | public void setupBasics(CtClass clazz) throws CannotCompileException, NotFoundException | { | if (basicsSet) return; | basicsSet = true; | // add serialVersionUID. | SerialVersionUID.setSerialVersionUID(clazz); | | // add marker interface. | clazz.addInterface(forName(AOP_PACKAGE + ".Advised")); | | // add aop helper class. | addHelperClass(clazz); | | if (isBaseClass(clazz)) | { | addBaseElements(clazz); | } | } | | | private boolean isBaseClass(CtClass clazz) | throws NotFoundException | { | if (clazz.getSuperclass() != null) | { | return !isAdvised(clazz.getSuperclass()); | } | return true; | } | So, when Extender gets instrumented, its superclass, Base, is not yet Advised. Extender therefore get an _instanceAdvisor attribute. Base then gets instrumented, and also receives an _instanceAdvisor attribute. Obviously, any call to _setInstanceAdvisor will only update Extender's _instanceAdvisor attribute, as Base's has been overridden. Now TreeCacheAOP comes along and appends an interceptor to Extender, but Base misses out. The upshot of all of this is that calling getAttribute() on Base will not result in the interceptor being called as the local _instanceAdvisor is null. However, calling getOther() will work as its _instanceAdvisor is correct. The problem really occurs because the optimized field wrappers use _instanceAdvisor directly, rather than calling _getInstanceAdvisor(). I assume this is for speed reasons (hence being called optimized!). Using aopc will work this out (at least I assume so). Certainly using aopc on the Base class, but using runtime transformation for the rest solves the problem. This is a significant issue, and I think the only general solution seems to be using _getInstanceAdvisor() in the field wrappers, unless of course the JVM changes its semantics to transform superclasses before subclasses. I don't have full knowledge of the infrastructure though, so perhaps there's a nice neat solution out there. Tim. View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3877581#3877581 Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=3877581 |