[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Sonic ESB class hierarchy causing unwanted multiple invocations of aspect

Oops, sorry about that!  Here's what you were looking for with call() and thisEnclosingJoinPointStaticPart:

O : Entering XQServiceEx.service(): void com.sonicsw.xqimpl.service.ServiceMessageHandler.callService(XQServiceContext)
O : Entering XQServiceEx.service(): void com.sonicsw.xqimpl.service.XQServiceChain.service(XQServiceContext)
O : Entering XQServiceEx.service(): void com.sonicsw.xqimpl.service.debug.DebugServiceInterceptor.intercept(XQInterceptorServiceContext)
  >>>> Inside of the actual service() method!
  >>>> About to exit the actual service() method!
O : Returned from XQServiceEx.service(): void com.sonicsw.xqimpl.service.debug.DebugServiceInterceptor.intercept(XQInterceptorServiceContext)
O : Returned from XQServiceEx.service(): void com.sonicsw.xqimpl.service.XQServiceChain.service(XQServiceContext)
O : Returned from XQServiceEx.service(): void com.sonicsw.xqimpl.service.ServiceMessageHandler.callService(XQServiceContext)

Because I hadn't gotten your response yet, I posted the same question earlier today at http://stackoverflow.com/questions/4807965/sonic-esb-class-hierarchy-causing-unwanted-multiple-invocations-of-aspect.  While I working on replying to you, I got a response there which suggested that I add !cflowbelow(call(void XQService.service(XQServiceContext))) to the pointcut, and that did the trick.  I'm getting only a single call for before(), around(), and after(), so I'm all set.

Thanks very much for your help, Andy.

Cheers,
Lee

-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Andy Clement
Sent: Wednesday, January 26, 2011 5:25 PM
To: aspectj-users@xxxxxxxxxxx
Subject: Re: [aspectj-users] Sonic ESB class hierarchy causing unwanted multiple invocations of aspect

The plot thickens.  If that is the trace for this pointcut (which I assume is what you have now):

pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
     execution(void XQService.service(XQServiceContext)) &&
     target(svc) &&
     target(com.sonicsw.xq.XQService) &&
     args(ctx);

then that is a bit odd.  I don't understand how this entry:

void com.ncr.eai.esb.ServiceFromAspect.service(XQServiceContext)

could be there, as ServiceFromAspect doesnt extend/implement XQService (so the execution shouldn't match).  and an instanceof the aspect is not an instance of XQService (so target shouldn't match). It smells a bit of something else messing with the bytecode as well as AspectJ and they aren't playing nicely together.

For an execution joinpoint both thisJoinPoint and thisEnclosingJoinPoint have the same signature :)  I wanted to see what happened with thisEnclosingJoinPoint and still using call().

If you want to sometimes skip the method you are best using around advice.

Andy

On 26 January 2011 12:44, Grey, Lee <Lee.Grey@xxxxxxx> wrote:
> Thanks for your reply, Andy.
>
> I may not need all 3 kinds of advice.  I definitely need to do some work in before() and after(), and I'd prefer to keep them as separate methods.  There are also some instances where I want to bypass the actual method invocation.  Can that be done from inside before()?  Or should I create my own doBefore() and doAfter() methods and call them from inside the around() advice?  Is that a best practice?
>
> The pointcut grew in complexity, because my advice was never executing.  I didn't really know why I had to add the things I did, but, for example, args(ctx) and target(svc) were added because nothing happened without them.
>
> I made the three changes you suggested and ran another test.  I removed the around() advice to reduce the noise.  I changed the call() in the pointcut to execution().  And I changed thisJoinPointStaticPart to thisEnclosingJoinPointStaticPart in the debug output.  To make it easier to read, here is the output trimmed to show only thisEnclosingJoinPointStaticPart.getSignature(), without svc, ctx, or this:
>
> O : Entering XQServiceEx.service(): void 
> com.sonicsw.xqimpl.service.XQServiceChain.service(XQServiceContext)
> O : Entering XQServiceEx.service(): void 
> com.sonicsw.xqimpl.service.XQServiceChain.XQInterceptorServiceWrapper.
> service(XQServiceContext) O : Entering XQServiceEx.service(): void 
> com.ncr.eai.esb.ServiceFromAspect.service(XQServiceContext)
>  >>>> Inside of the actual service() method!
>  >>>> About to exit the actual service() method!
> O : Returned from XQServiceEx.service(): void 
> com.ncr.eai.esb.ServiceFromAspect.service(XQServiceContext)
> O : Returned from XQServiceEx.service(): void 
> com.sonicsw.xqimpl.service.XQServiceChain.XQInterceptorServiceWrapper.
> service(XQServiceContext) O : Returned from XQServiceEx.service(): 
> void 
> com.sonicsw.xqimpl.service.XQServiceChain.service(XQServiceContext)
>
> It seems like excluding anything from package com.sonicsw.* should do the trick.  Why didn't those !within() attempts work?
>
> Thanks for your help,
> Lee
>
>
> -----Original Message-----
> From: aspectj-users-bounces@xxxxxxxxxxx 
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Andy Clement
> Sent: Wednesday, January 26, 2011 3:10 PM
> To: aspectj-users@xxxxxxxxxxx
> Subject: Re: [aspectj-users] Sonic ESB class hierarchy causing 
> unwanted multiple invocations of aspect
>
> Hi,
>
> Quite tricky to get my brain around...  Do you really need all 3 kinds of advice in there, or would you settle for one? That may help with producing less debug and understanding the situation.
>
> If you don't need the 'this' at the join point (which you don't seem 
> to bind in the pointcut), I would recommend using execution() rather 
> than call(). (If the weaver will able to access the execution() 
> joinpoint for weaving)
>
> I would also be interested in the output of thisEnclosingJoinPointStaticPart to give us an idea of what method is making the call.  That will give us the static information about the call site (where this/target give you the runtime information) - possibly based on that we can construct a better pointcut.
>
> Andy
>
> On 25 January 2011 18:20, Grey, Lee <Lee.Grey@xxxxxxx> wrote:
>> Howdy.  I'm trying to use AspectJ with Sonic ESB to intercept calls 
>> to the
>> service() method of any custom ESB service.  That means I don't know 
>> the type of the service class in advance; I only know that it 
>> implements interface XQServiceEx.  The implemented service() method 
>> is invoked by the Sonic container every time a JMS message arrives at the service endpoint.
>> However, the container has a somewhat complex internal structure, and 
>> I'm getting three invocations of my advice for each inbound message.
>> (I hope my terminology isn't too far off.)
>>
>> My aspect looks like this:
>>
>>
>> package com.ncr.eai.esb.aop;
>>
>> import com.sonicsw.xq.XQService;
>> import com.sonicsw.xq.XQServiceEx;
>> import com.sonicsw.xq.XQServiceContext; import 
>> com.sonicsw.xq.XQServiceException;
>> import com.ncr.eai.esb.*;
>>
>> aspect XQServiceAspect {
>>  final String id = "O : ";
>>
>>  pointcut serviceCall(XQServiceEx svc, XQServiceContext ctx) :
>>      call(void XQService.service(XQServiceContext)) &&
>>      target(svc) &&
>>      target(com.sonicsw.xq.XQService) && //     within(com.ncr..*) &&
>>      args(ctx);
>>
>>     before(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx):
>> serviceCall(svc, ctx) {
>>      System.out.println(id + "Entering XQServiceEx.service(): " +
>> thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " 
>> + this);
>>     }
>>
>>     void around(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx):
>> serviceCall(svc, ctx) {
>>      System.out.println(id + "In the around() advice before call to
>> XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + "
>> " + svc + " " + ctx + " " + this);
>>      proceed(svc, ctx);
>>      System.out.println(id + "In the around() advice after call to
>> XQServiceEx.service(): " + thisJoinPointStaticPart.getSignature() + "
>> " + svc + " " + ctx + " " + this);
>>      }
>>
>>
>>     after(com.sonicsw.xq.XQServiceEx svc, XQServiceContext ctx) returning:
>> serviceCall(svc, ctx) {
>>      System.out.println(id + "Returned from XQServiceEx.service(): " 
>> +
>> thisJoinPointStaticPart.getSignature() + " " + svc + " " + ctx + " " 
>> + this);
>>     }
>> }
>>
>>
>> The output looks like this:
>>
>>
>> O : Entering XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain@c64bc2
>> com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765
>> com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : In the around() advice before call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain@c64bc2
>> com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765
>> com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : Entering XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
>> @
>> 195638a
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : In the around() advice before call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
>> @
>> 195638a
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : Entering XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.ncr.eai.esb.ServiceFromAspect@1510b03
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : In the around() advice before call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.ncr.eai.esb.ServiceFromAspect@1510b03
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>>   >>>> Inside of the actual service() method!
>>   >>>> About to exit the actual service() method!
>> O : In the around() advice after call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.ncr.eai.esb.ServiceFromAspect@1510b03
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : Returned from XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.ncr.eai.esb.ServiceFromAspect@1510b03
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : In the around() advice after call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
>> @
>> 195638a
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : Returned from XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
>> @
>> 195638a
>> com.sonicsw.xqimpl.service.XQServiceChain$XQServiceContextWrapper@19c
>> 7 05e com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : In the around() advice after call to XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain@c64bc2
>> com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765
>> com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>> O : Returned from XQServiceEx.service(): void
>> com.sonicsw.xq.XQService.service(XQServiceContext)
>> com.sonicsw.xqimpl.service.XQServiceChain@c64bc2
>> com.sonicsw.xqimpl.service.XQServiceContextImpl@97e765
>> com.ncr.eai.esb.aop.XQServiceAspect@d8ce8f
>>
>>
>> I know the results of my experimentation are kind of hard to read 
>> here, but each call to service() results in a sequence of three calls 
>> from com.sonicsw.xqimpl.service.XQServiceChain,
>> com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper
>> , and com.ncr.eai.esb.ServiceFromAspect.  I only want to see one call 
>> per message, meaning one call to service().  And I don't know in 
>> advance what the name of the third class will be.  This test is being 
>> run with com.ncr.eai.esb.ServiceFromAspect, but there may be dozens 
>> of other classes, and I don't want to have to hard-code them; they 
>> need to be discovered.  I tried to add the commented out 
>> within(com.ncr..*)phrase, but using that prevented the pointcut from 
>> working at all.  I also tried to exclude com.sonicsw packages with 
>> things like !within(com.sonicsw..*), but that also stopped all pointcuts from working.
>>
>> As far as deployment goes, I've got this aspect jarred up, and I'm 
>> doing load-time weaving by adding javaagent to the container 
>> command-line.  The overall strategy is working, but I have spent 
>> longer than I want to admit trying to construct a pointcut that works as expected.
>>
>> Any "advice" appreciated!
>>
>> Thanks,
>> Lee Grey, SOA Architect
>> NCR
>>
>> _______________________________________________
>> aspectj-users mailing list
>> aspectj-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users