[
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 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
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
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