Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Examining a destructive read in an aspect

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.Grey@xxxxxxx> 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-bounces@xxxxxxxxxxx
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Grey, Lee
> Sent: Wednesday, February 02, 2011 11:45 PM
> To: aspectj-users@xxxxxxxxxxx
> 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-bounces@xxxxxxxxxxx
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Ramnivas Laddad
> Sent: Monday, January 31, 2011 8:50 PM
> To: aspectj-users@xxxxxxxxxxx
> 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.Grey@xxxxxxx> 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@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>


Back to the top