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