I think you really should be able to single out the ones you are interested in at compile time. I probably would have used withincode() to scope exactly the one I'm interested in:
// Select the call to getNextIncoming() made within the method XQServiceEx.service() pointcut getIncoming(XQServiceContext ctx) : call(XQEnvelope XQServiceContext.getNextIncoming()) && target(ctx) && withincode(* XQServiceEx.service()); But I can't immediately see why your within() (which is just a broader form of withincode really) isn't working for you. Andy On 3 February 2011 10:07, Grey, Lee <lee.g...@ncr.com> wrote: > I think I have a solution, but I'm not sure whether it violates a best > practice (or is just beneath a good aspect developer): > > I created a ThreadLocal<Boolean> to determine which invocations should be > advised and which should not: > > private static final ThreadLocal<Boolean> tlAdvise = new > ThreadLocal<Boolean>() { > @Override protected Boolean initialValue() { return true; } > }; > Then I set the ThreadLocal to false when I want to run the real methods and > to true when I want them to be short-circuited with my own advise: > > ... > tlAdvise.set(false); > if( ctx.hasNextIncoming() ) { // call the real Sonic code > System.out.println("In beforeCallToService: hasNextIncoming returned > true"); > XQEnvelope env = ctx.getNextIncoming(); // call the real Sonic code > tlAdvise.set(true); > ... > My pointcuts use if: > > pointcut hasIncoming() : > execution(boolean XQServiceContext.hasNextIncoming()) && > if(tlAdvise.get()); > and > > pointcut getIncoming() : > execution(XQEnvelope XQServiceContext.getNextIncoming()) && > if(tlAdvise.get()); > Is this a brute-force solution to something that could be done far more > elegantly and efficiently with just a little more pointcut knowledge? Is > there anything that makes this a bad idea? > > Thanks for your insights, > Lee > ________________________________ > From: aspectj-users-boun...@eclipse.org > [mailto:aspectj-users-boun...@eclipse.org] On Behalf Of Grey, Lee > Sent: Wednesday, February 02, 2011 11:45 PM > To: aspectj-users@eclipse.org > Subject: Re: [aspectj-users] Examining a destructive read in an aspect > > I've done what you suggested, and I think it would work fine, except that I > can't get the pointcut right for the two calls I need to intercept. I seem > to be getting all or nothing. > > What pointcut would intercept the calls to ctx.hasNextIncoming() and > ctx.getNextIncoming() when they come from the actual XQServiceEx.service() > method but would still make the real, unadulterated calls when made from > inside my aspect? > > My failed attempts include > > pointcut hasIncoming() : call(boolean XQServiceContext.hasNextIncoming()) && > !within(com.sonicsw..*); > > pointcut getIncoming(XQServiceContext ctx) : call(XQEnvelope > XQServiceContext.getNextIncoming()) && target(ctx) && (within(XQService) || > within(XQServiceEx)); > > and other unsuccessful flailing. I find creating successful pointcuts to be > black magic. > > Thanks, > Lee > ________________________________ > From: aspectj-users-boun...@eclipse.org > [mailto:aspectj-users-boun...@eclipse.org] On Behalf Of Ramnivas Laddad > Sent: Monday, January 31, 2011 8:50 PM > To: aspectj-users@eclipse.org > Subject: Re: [aspectj-users] Examining a destructive read in an aspect > > You could do something along the following lines: > 1. In your before advice read destructively as needed and store away the > result 'env' in a ThreadLocal. > 2. Advise ctx.getNextIncoming() with an around advice to return the stored > result (and don't call proceed() in it). > -Ramnivas > > On Mon, Jan 31, 2011 at 2:59 PM, Grey, Lee <lee.g...@ncr.com> wrote: >> >> I've been working on intercepting the service() method invocation in a >> Sonic ESB container. I had just started to write my before() advice when >> the bad news dawned on me. Just about every ESB service() method starts >> with the following... >> >> public void service(XQServiceContext ctx) throws XQServiceException { >> XQEnvelope env = null; >> while (ctx.hasNextIncoming()) { >> env = ctx.getNextIncoming(); >> if (env != null) { >> XQMessage msg = env.getMessage(); >> That call to ctx.getNextIncoming() is a destructive read that returns a >> different XQEnvelope every time it's called. The problem is that I need to >> evaluate the contents of the message that comes from ctx.getNextIncoming() >> in my before() advice. What that means is that the call to >> ctx.getNextIncoming() in the service() method is not going to get the >> message, because the before() advice already got it. >> >> Now I'm wondering if there's a way to put an aspect around >> ctx.getNextIncoming() to make it deliver the message again. Or if I can >> somehow clone ctx so that I can read the cloned message in before() and then >> read it from the real XQServiceContext object in service(). >> XQServiceContext doesn't offer any way to peek or browse, and it doesn't >> have a method to put a message, either. >> >> I would imagine I'm not the first person to run into this kind of issue >> with AOP before. I'm hoping that there's a pattern to address it. >> >> Thanks, >> Lee Grey >> _______________________________________________ >> aspectj-users mailing list >> aspectj-users@eclipse.org >> https://dev.eclipse.org/mailman/listinfo/aspectj-users >> > > > _______________________________________________ > aspectj-users mailing list > aspectj-users@eclipse.org > https://dev.eclipse.org/mailman/listinfo/aspectj-users > > _______________________________________________ aspectj-users mailing list aspectj-users@eclipse.org https://dev.eclipse.org/mailman/listinfo/aspectj-users