Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Design Question Dynamic Interceptors

Can you point me to any resources which discuss this in more detail?

I guess i am most interested in how the aspectweaver/classloader is loading the pointcuts/advice. Also is there some internal api which can be called to say add pointcut/advice via api?

Thanks

Andy Clement wrote:
We do support some degree of hotswap class replacement (similar to
what happens if you change a class and update it in the VM 'live'
during debugging for example) - but we don't manage that for you, you
would have to drive the class replacement.
What about if i am using aop.xml and not Annotations. Is there any difference??
  Or in an OSGi environment
the bundles can be dynamically refreshed (meaning unloaded then
reloaded, but possibly woven with a different set of aspects on
reload).  Or you can manage classloaders yourself and discard that
which has loaded the code so far and create a new one that will reload
with a potentially different set of aspects that include more
pointcuts/advice.  But basically reloading has to happen for
*load*time weaving to do something different.

When you say:
  
All of the points are not known at deploy time.
    
Can it really be *any* join point?  or is it more like 'execution of
any public method' - so execution(public * *(..)) or something like
that? Since I typically see this usually done by weaving all places
that might ever want interception and writing highly optimal advice
that can do very fast checks for whether there is 'nothing to do' at
the various locations.  Something like these two levels of check:

pointcut interceptionLocation(): executionOfSomethingInteresting() &&
if(InterceptorFramework.anythingSwitchedOnAnywhere);

Object around(): interceptionLocation() {
  if (!InterceptorFramework.anythingToDoHere(thisJoinPointStaticPart)) {
    return proceed();
  }
  // do stuff
}

The if() guard in the pointcut will prevent construction of the
thisJoinPoint object (which can be expensive) if the advice is not
actually going to be called.

Ordering of advice is usually achieved using 'declare precedence:' to
specify a partial ordering amongst aspects that may apply at a
particular join point - since between different aspects it is
deliberately undefined unless you say otherwise.  Within an aspect the
order of application of advice is well defined so you can usually get
what you want by arranging your before/after/around advice as
appropriate.  If you attempt an arrangement that confuses AspectJ, it
will tell you.

Andy.

2008/12/3 Jason Weinstein <Jason.Weinstein@xxxxxxx>:
  
I am using LTW with use of aop.xml and a single "aj" file. However i don't
really see how AspectJ supports the addition and deletion of Aspects at
runtime. In a way i want to weave and unweave new pointcuts/advice at
runtime. In fact i'd like for a user to be able to specify them.

I would like to be able to

1) Add and Remove interceptors at runtime. Interceptors apply at specific
points in the code (pointcut). All of the points are not known at deploy
time.

For instance i would like to be able to add and remove an around() advice
for Class/Interface A Method X at runtime

2) I would like to be able to chain the Interceptors.

For instance for method X i would like to first apply Interceptor A, then
Interceptor B, then call the original Method X (or skip it).

To accomplish this i came up with a little framework which manages an
Interceptor Table/Chains
It allows for the dynamic addition and deletion of Interceptors as well as
their chaining.
The framework code is called from the aspect "aj" file.
So largely these pointcuts are static. However the Interceptor behavior is
dynamic. (I'm being very specific and don't have a *.*(..) pointcut)
The advice in the "aj" code simple calls into my framework which is kind of
like a DI (dynamic invocation) framework.

The question is is there a way to dynamically add and remove new
pointcuts/advice at runtime, and ensure the order they are woven?.

Some example code which illustrates some ideas is shown below.

  public pointcut DeliveryChannel_accept1(
      DeliveryChannel object) :
      execution(public MessageExchange
javax.jbi.messaging.DeliveryChannel+.accept())
      && this(object);


  Object around(DeliveryChannel object,
                long timeout)
                throws MessagingException :
      DeliveryChannel_accept1(object, timeout) {
      Proceed proceed = new Proceed() {
                   // This is the actual target code. At the end of an
InterceptorChain this code may be called.
          public Object invoke(Object target, Object[] args) throws
Exception {
              DeliveryChannel channel = (DeliveryChannel) target;
              long timeout = (Long) args[0];
              return proceed(channel, timeout);
          }
      };
      Object result = null;
      try {
          result = system.invoke(JBIConstants.KEY_DELIVERYCHANNEL_ACCEPT1,
// This code calls my framework, which
                  thisJoinPoint, proceed);
                                             //1. Looks up the list of
Interceptors to apply (can be empty)
      } catch (MessagingException e) {
                                       //2. Runs each interceptor with args
from JoinPoint passed in
          throw e;
                                                      //3. Calls the Proceed
object which runs the actual target method
      } catch (RuntimeException e) {
          throw e;
      } catch (Exception e) {
          throw new RuntimeException(e);
      }
      return result;
  }


Interceptors have a simple api like

  public Object invoke(IInterceptorChain chain) throws Exception;

The InterceptorChain has methods like

  public String getKey();

  public void setKey(String key);

  public Object getTarget();

  public void setTarget(Object target);

  public Member getMember(); // Constructor or Method

  public void setMember(Member member);

  public Object[] getArgs();

  public void setArgs(Object[] args);

  public Object proceed() throws Exception;

Where proceed() is implemented something like

  public Object proceed() throws Exception {
      Object ret;
      if (getIter().hasNext()) { // Iter contains list of Interceptors
          ret = getIter().next().invoke(this);
      } else {
          wasTargetCalled = true;
          ret = getProceed().invoke(target, args);
      }
      return ret;
  }

and Proceed abject has simple api like

  public Object invoke(Object target, Object[] args) throws Exception;


The table of Interceptors has methods like

addKey(key, Interceptor)
getListForKey(key)
removeInterceptor(Interceptor)


There are a variety of types of Interceptors including basic ones which only
run if Filter passes, etc


_______________________________________________
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