Community
Participate
Working Groups
ENV: Eclipse 3.4 AJDT 1.6.3 Spring 2.5 JDK 1.6 Windows XP SP2 I have Annotation based AOP on Spring managed beans and on objects that are not managed by Spring. Only certain methods run into the above error. If I tweak my pointcut expression to limit the markers, evrything in Eclipse and Jetty works fine. Example method body that shows the error: ***** public boolean isUserAuthrized(long docId, String userId) { return priceUtilDao.isUserAuthrized(docId, userId); } ******** Pointcut: @Pointcut("execution(* *..business..*(..))") public void businessServiceLayer() { } If I use @Pointcut("execution(* *..business..get*(..))") public void businessServiceLayer() { } Jetty and Junit work just fine. A regualr compile works fine and runs fine in weblogic 103. Junit tests and jetty launch throw the above error.
adding myself to the mail-
can you include the exception stack trace please?
Created attachment 127055 [details] Error stack trace for Bug id: 266564 Error stack trace attached.
From the stack trace we see that the verifyerror is in some generated around advice in PWSPriceUtilImpl.isPriceDocAuthrized_aroundBody23$advice. java.lang.VerifyError: (class: com/uprr/app/pws/client/price/business/PWSPriceUtilImpl, method: isPriceDocAuthrized_aroundBody23$advice signature: (Lcom/uprr/app/pws/client/price/business/PWSPriceUtilImpl;JLjava/lang/String;Lorg/aspectj/lang/JoinPoint;Lcom/uprr/app/pws/client/price/aop/TraceInterceptor;Lorg/aspectj/lang/ProceedingJoinPoint;)Ljava/lang/Object;) Register 2 contains wrong type Presumably this is because of one of the join points that the unrestricted pointcut (that didn't specify a name) matched upon in the PWSPriceUtilImpl class. My current thought based on the signature of the method: public boolean isUserAuthrized(long docId, String userId) is that the weaver is not allowing for a long which consumes two slots rather than just one.
Yup, that is it - very serious bug. This program will crash in the same way: --- package business; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; public class AA { public void foo(long docId, String userid) { } public static void main(String[] args) { new AA().foo(12, "hello"); } } @Aspect class Asp { @Around("execution(* foo(..))") public Object around(ProceedingJoinPoint pjp) { return pjp.proceed(); } } ---
In the bytecode for the method: private static final java.lang.Object foo_aroundBody1$advice(business.AA, long, java.lang.String, org.aspectj.lang.JoinPoint, business.Asp, org.aspectj.lang.ProceedingJoinPoint); Synthetic: true Code: Stack=5, Locals=8, Args_size=6 0: aload 6 2: astore 7 4: aload_0 5: lload_1 6: aload_2 7: aload 7 9: invokestatic #70; //Method foo_aroundBody0:(Lbusiness/AA;JLjava/lang/String;Lorg/aspectj/lang/JoinPoint;)V 12: aconst_null 13: areturn At instruction 6 we attempt aload_2 - that should have allowed for the long taking up 2 slots and been an aload_3
Awesome! You are right on the mark. However I am surprised as to why the weaver behavior is different in Eclipse vs. the regularly deployed ear package? For now I am changing the method signatures to use int. Also, is using an Object instead of a primitive help? Thank you for such a quick discovery.
With reference my question/comment regarding using an Object vs a primitive Using a "Long" works well. It may be a little work, but it is a better work around. Thanks.
> However I am surprised as to why the weaver behavior is different in > Eclipse vs. the regularly deployed ear package? Not quite sure - the probable reason is that in eclipse something happened that meant it decided to not weave via inlining, but instead decided to use a closure class. This can be forced with the -XnoInline option, and indeed if I force that test program to compile with no inlining: ajc -XnoInline -1.5 AA.java then it runs fine. Sometimes the decision on whether inlining can occur can be for very simple reasons like the order in which the weaver encountered the types. So if your eclipse and the later load-time weaver touched the types in a different order that might explain it.
Ok - fixed it. It was the code to convert the proceed() call into a method call - it did not prepare the arguments correctly. A messy workaround is to expose the parameter as context and pass them on proceed, that avoids the weaver trying and getting it wrong: @Around("execution(* foo(..)) && args(l,s)") public Object around(ProceedingJoinPoint pjp,Long l, String s) { return pjp.proceed(new Object[]{l,s}); } Anyway, the fix will be in the next dev build. The fastest workaround for you would probably be putting -XnoInline in the weaver options section of your aop.xml: <weaver options="-XnoInline"/>
Thank you. This has been one of the fastest resolutions I have come across. I will use the weaver options until the next stable release.