-
1. Re: Invocation running on wrong field
dunks80 Oct 17, 2005 9:39 AM (in response to dunks80)Using jboss-aop 1.3.1
After some more debugging through the jboss-aop source I think I know what's going on but I 'm not 100% certain why, or if it's my fault or if it's a bug. Keep in mind this only happens when I run the class using standalone aop (both precompiled and loadtime) with the following jvm args-Djboss.aop.verbose=true -Djboss.aop.prune=true -Djboss.aop.optimized=true -Djboss.aop.include=com.tura -Djboss.aop.exclude=org,com,bsh,net,antlr -Djboss.aop.class.path=/home/gdunkle/workspace/insight-core/ -javaagent:/usr/local/jboss/server/dev/deploy/jboss-aop.deployer/jboss-aop-jdk50.jar
as said before eveything works fine when using loadtime weaving in JBoss AS 4.0.3.
Ok so debuging through the code it seems that when the class is being advised the field access transformer believes that there are only three fields in my class and that the annotated field is number 1 in the array of fields...this is correct except for one detail. My class extends from another class which also has a field. So when I look as the final invocation class being invoked by my test in the debugger the advised fields array has a length of 4. The inherited field is in the 0 slot pushing the annotated field up from the 1 slot (which is where the advised class believes it to be) to the 2 slot. So when I call invocation.resolveAnnotation(MyAnnotaion.class) it resolves to a null annotation because it's looking at the wrong field. I'm going to continue to dig into this but I think it's a possible bug unless I'm somehow running this incorrectly. -
2. Re: Invocation running on wrong field
dunks80 Oct 17, 2005 10:51 AM (in response to dunks80)Ok I'm pretty sure this is a bug. I've checked out the code in question from both jboss-head and jboss-aop and it's the same in both places here's where i think i'm seeing the problem....
line 89 in org.jboss.aop.instrument.FieldAccessTransformer// Public -------------------------------------------------------- protected void buildFieldWrappers(CtClass clazz, ClassAdvisor advisor) throws NotFoundException, CannotCompileException { List fields = Instrumentor.getAdvisableFields(clazz); int fieldIndex = fieldOffset(clazz.getSuperclass()); JoinpointClassification[] classificationGet = classifyFieldGet(clazz, advisor); JoinpointClassification[] classificationSet = classifyFieldSet(clazz, advisor); Iterator it = fields.iterator(); boolean skipFieldInterception = true; for (int index = 0; it.hasNext(); index++, fieldIndex++) { CtField field = (CtField) it.next(); if (!isPrepared(classificationGet[index]) && !isPrepared(classificationSet[index])) { continue; } if (!javassist.Modifier.isPrivate(field.getModifiers())) { skipFieldInterception = false; } Shouldn't we be passing field index instead of index? --> doBuildFieldWrappers(clazz, field, index, classificationGet[index], classificationSet[index]); } if (skipFieldInterception) { advisor.getManager().skipFieldAccess(clazz.getName()); } else { advisor.getManager().addFieldInterceptionMarker(clazz.getName()); } }
The call to doBuildFieldWrappers goes to org.jboss.aop.instrument.OptimizedFieldAccessTransformer which has a method signature like thisprotected void doBuildFieldWrappers(CtClass clazz, CtField field, int fieldIndex,JoinpointClassification classificationGet, JoinpointClassification classificationSet) throws NotFoundException, CannotCompileException
So i'm pretty sure the third argument should be the fieldIndex which takes into account inherited field offset instead of just index. I"m going to file a bug in Jira and see what happens. -
3. Re: Invocation running on wrong field
kabirkhan Oct 17, 2005 12:55 PM (in response to dunks80)Thanks for the fix. I've added it along with a test to jboss-head. However, in the 1.3.x branch I could not get it to fail?
Can you please take a look at the testcase I've used to see if I am missing anything? It is under aop/src/resources/test/regression/jboss-aop.xml, and src/test/org/jboss/test/aop/regression/inheritedfield. -
4. Re: Invocation running on wrong field
dunks80 Oct 17, 2005 1:57 PM (in response to dunks80)I'm having a hard time building jboss-head right now so i'm not of much help.
Your fix fixed my problem...i just checked out aop from jboss-head replaces the old aop libraries my test was using with the new ones. debugged through the code and it's now invoking on the correct field. I looked over you test case and couldn't figure out why it would fail in 1.3.x branch. My interceptor was failing specifically when I was looking for the annotation of a field. here is a look at the invoke method of my interceptorpublic Object invoke(Invocation invocation) throws Throwable { System.out.print("Invocation : " + invocation.getTargetObject()); //was failing here because it was looking at the wrong field (index instead of fieldIndex) to resolve the annotation Service serviceProvider = (Service) invocation.resolveAnnotation(Service.class); Object serviceObject = null; if (serviceProvider != null) { ServiceLookup SERVICE = new DefaultServiceLookup(serviceProvider.lookup(), serviceProvider.cache(), serviceProvider.lookupType()); serviceObject = ServiceLocator.lookupService(SERVICE); } invocation.invokeNext(); return serviceObject; }
perhaps a testcase which tries to retrieve an annotated field would help? -
5. Re: Invocation running on wrong field
dunks80 Oct 17, 2005 3:00 PM (in response to dunks80)So oddly enough my test now works with the patched jboss-aop-jdk50.jar but if i replace the old jboss-aop-jdk50.jar sitting in my jboss-aop.deployer folder on my server and run the class that my test was testing things don't work. Perhaps I can't just do a drop in replacement of jboss-aop-jdk50.jar? It's no big deal right now because what wasn't working prior to the patch runs standalone and so i can just point it's classpath to the patched jar. Meanwhile my interceptor always worked when running on the JBoss server with loadtime weaving. Question though, would we see the fixed jboss-aop released with jboss 4.0.4? Thanks
-
6. Re: Invocation running on wrong field
kabirkhan Oct 18, 2005 11:52 AM (in response to dunks80)"dunks" wrote:
So oddly enough my test now works with the patched jboss-aop-jdk50.jar but if i replace the old jboss-aop-jdk50.jar sitting in my jboss-aop.deployer folder on my server and run the class that my test was testing things don't work. Perhaps I can't just do a drop in replacement of jboss-aop-jdk50.jar? It's no big deal right now because what wasn't working prior to the patch runs standalone and so i can just point it's classpath to the patched jar. Meanwhile my interceptor always worked when running on the JBoss server with loadtime weaving.
You've got me confused :-)"dunks" wrote:
Question though, would we see the fixed jboss-aop released with jboss 4.0.4? Thanks
Definitely -
7. Re: Invocation running on wrong field
kabirkhan Oct 20, 2005 12:36 PM (in response to dunks80)Can you please provide a scaled down version of what broke it for you with 1.3.1, so I can fix this in the 1.3 branch? You can send it to me directly.
Thanks -
8. Re: Invocation running on wrong field
dunks80 Oct 21, 2005 8:56 AM (in response to dunks80)Sorry about the confusing post I'll try to explain again. My interceptor and custom annotation are basically used for injection (looking up object in jndi). The interceptor always worked in JBoss 4.0.3 with load time weaving. So In other words I could annotate my classes and when running in the container my interceptor would be correctly invoked on the annotated fields.
I also unit test those classes which have annotated fields outside the server environment. I accomplished this using standalone aop and embeddable ejb. That is when I found the bug.
Your fix (changing index to fieldIndex in the call to doBuildFieldWrappers) fixed my problem in my testing environment. I pulled your fix from jboss-head built the new jjars and placed them in my classpath. The interceptor now invokes on the correctly annotated field.
What I was trying to convey in my last post was that for the sake of consistency I felt I should use the same jboss-aop-jdk50.jar both for testing and for running on the server. So I took the jar I had created from the latest code in jboss-head and overwrote the existing jboss-aop-jdk50.jar in my server's jboss-aop.deployer folder. When I did this however my interceptor failed to work in the container and gave no indication as to why. I had already spent alot of time on the problem and felt that since I had a jar that would allow me to test the annotated classes outside the container and since the annotated classes always worked inside the standard container I would just not worry about using the same jar for both standalone testing and running in the container. I hope that makes more sense.
Ok so a scaled down version of what initially broke could be something like this...
Annotation...@Target( { ElementType.FIELD }) public @interface MyAnnotation { }
Interceptor...@InterceptorDef(scope = Scope.PER_VM) @Bind(pointcut = "get(* *->@MyAnnotation)") public class MyInterceptor implements Interceptor { /** * returns the name of the interceptor...I just use the fully qualified * classname */ public String getName() { return MyInterceptor.class.getName(); } /** * Interceptor invocation. Uses the values of the annotation to determine * what service to lookup and set. */ public Object invoke(Invocation invocation) throws Throwable { System.out.print("Invocation : " + invocation.getTargetObject()); MyAnnotation myAnnotation = (MyAnnotation) invocation.resolveAnnotation(Service.class); Object serviceObject = null; if myAnnotation != null) { System.out.print("Found an annotation!"); } invocation.invokeNext(); return serviceObject; } }
Class the uses the interceptor...public class MyClass implements Serializable { @MyAnnotation private SomeOtherClass annotatedField public BackingBean() { super(); } public void doSomething() { annotatedField.someCall(); } }
A testpublic class Test { @org.testng.annotations.Test public void testDoSomething()throws Exception { MyClass myClass=new MyClass(); myClass.doSomething(); } }
I hope that helps you out