Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Regarding queuing methods using AspectJ

Hi Sarthak,

There are a few difficultys with what your attempting, mainly to do with how complex the methods are.

If you were wanting to do this with static methods then it would be very simple, in fact your pseudo code would pretty much work.

Instance methods become a little more complex, but not really a hinderance as all you need to do is store the relavent instance in the intial pointcut. Something like this would do the trick:

===============

Map<Object, Method> objectsToMethods = new HashMap<Object, Method>();

pointcut A(Object obj): execution (myMethodA) && this(obj);

void around(Object obj): A(obj)
{
objectsToMethods.put(obj, ((MethodSignature)thisStaticJoinPoint.getSignature()).getMethod());
// I don't want to proceed with the execution of the method right now
}

pointcut C: execution (myMethodC)

void around(): C()
{
   for(Object obj : objectsToMethods.getKeys()
      objectsToMethods.get(obj).invoke(obj);
}

==============

Simple enough.

Problems will start to appear when you want to provide arguments to the method as you'll have to use a "args" designator for each argument in the method, which might get abit much after while. Especially if you have lots of arguments as your datastructure for keeping references on the object, method, arguements will start to becomeabit complicated.

Heres a simple one for a method called with an String

================
Map<Object, Object[]> objects = new HashMap<Object, Object[]>();

pointcut A(Object obj, String): execution (myMethodA (String string) && this(obj) && args(string);

void around(Object obj, String string): A(obj, string)
{
Object[] objs = {((MethodSignature)thisStaticJoinPoint.getSignature()).getMethod(), string};
   objectsToMethods.put(obj, objs);
// I don't want to proceed with the execution of the method right now
}

pointcut C: execution (myMethodC)

void around(): C()
{
   for(Object obj : objectsToMethods.getKeys()
      Object[] objs = objectsToMethods.get(obj);
       objs[0].invoke(obj, objs[1]);
}

==============


As with most things it depends on what kind of thing your doing and how much your going to be doing it! If your want this to work with any method with a variable amount of args then your going to have to resort to the "joinpoint" instance within your advice. Something like this would do the trick:

================
Map<Object, Method> objectsToMethods = new HashMap<Object, Method>();
Map<Object, Object[]> objectsToArgs = new HashMap<Object, Object[]>();

pointcut A(Object obj): execution (myMethodA) && this(obj);

void around(Object Obj): A(obj)
{
objectsToMethods.put(obj,((MethodSignature)thisStaticJoinPoint.getSignature()).getMethod() );
   objectsToArgs.put(obj, thisJoinPoint.getArgs());
// I don't want to proceed with the execution of the method right now
}

pointcut C: execution (myMethodC)

void around(): C()
{
for(Object obj : objectsToMethods.getKeys()) objectsToMethods.get(obj).invoke(obj, objectsToArgs.get(obj);
}
==============

That would do it for pratically everything. The only problem being the performance impact of using the thisJoinPoint instance thats said to have quite a negative effect. If performance is a consideration in your system then i'd try and stick to one of the first two options or prehaps rethink the design abit. If each of these methods is likely to be run by seperate threads then a CyclicBarrier would be the solution or if you've only got one to play with then maybe think about using a few booleans to state that a particular task needs to be completed.

Got on abit of ramble there, hopefully some of that will help you solve your problem!

Have a nice day.

Tom


Sarthak Grover wrote:

Hello all,

What started with as a simple idea is turning out more confusing than
I initially thought (or I am making it that way for myself)

What I am trying to achieve is a transaction queue which is executed
only when a particular method is called.

Currently I have a bunch of pointcuts identifying methods which I want
to capture and prevent execution till the 'trigger' method is called.
So, my pseudo algorithm
was something like this:

In the following, myMethodA, myMethodB are the target methods that I
want to queue and myMethodC is the trigger method.

===================
pointcut A: execution (myMethodA)

void around(): A()
 {
  Add the methodCall(joinpointSignature) to an ArrayList();
// I don't want to proceed with the execution of the method right now
 }

pointcut B: execution (myMethodB)

void around() : B()
 {
 Add the methodCall to the above ArrayList();
 }

pointcut C: execution (myMethodC)

void around(): C()
{

Execute myMethodA();
Execute myMethodB();
}

===================
I am able to save the method information using reflection, but I am
not sure how to make a call in the advice of myMethodC to execute
myMethodA() and myMethodB() from within the aspect.

Is there some way of saving the state of these methods and then
executing them? Perhaps there is a simpler way and I am just not aware
of it?

I appreciate any ideas or advice in this regards.

Thanks,

Sarthak
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



--
Kind Regards

Tom Coupland, Systems Developer
Direct: +44 (0) 1225 731412
tom.coupland@xxxxxxxxxxxxxx  http://www.metacharge.com/

< Merchant accounts from a choice of tier 1 banks >
< Card payment processing for ecommerce merchants >
< Low rates, fast-track application, 24x7 merchant support > < Enterprise grade account management and reporting software >
< Metacharge is a Visa/MasterCard certified member service provider >



Back to the top