Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Incremental and runtime weaving support ?

Hi again, I have just read your email Ron and I see that around advice is tricky. I like your proposed solution. I don't think it is complex. It is coherent. If you have a pointcut that intercepts advice execution then thisJoinPoint must have information about the intercepted advice. It seems coherent to me. Under my point of view if we put another pointcut in the language (like adviceexecution) then we must update thisJoinPoint API to be able to retrieve information about it. ThisJoinPoint must be equal useful for all the joinPoints.

I'm worried (again) about performance. Is thisJoinPoint a performance bottleneck? Implementing Ron's proposal would be a bad idea from a performance point of view? If so a lazy loading strategy would be useful to populate thisJoinPoint.

An use case for dynamic aspects. Suppose I want to build an application server that offers several crosscutting services (security, logging, performace metrics, etc.). It seems that AspectJ is a good technology to do this. But if I want to be able to stop/start this services (potentially implemented with around advice) or change service implementation with a custom one (this could be done with chain advice).  It is very interesting to be able to "deploy pointcuts" that match my own code. Example of this. The application server expose a trace service with the following "interface":

public abstract aspect TraceService implements DynamicAspect
{
    abstract pointcut enterMethod(String methodName);
    abstract pointcut exitMethod(String methodName);

    // Follows advice that could use a chain advice pattern
    ...
}


I want customize the trace service for my own servlets and EJBs but I don't want to touch any line of my code so I write the following aspect:

public aspect MyTraceService extends TraceService
{
    /* MyTraceService only traces exactly what the programmer wants. */
    pointcut enterMethod(String methodName): /* specific pointcuts of my code that I'm interested to trace */;
    pointcut exitMethod(String methodName):/* specific pointcuts of my code that I'm interested to trace */;
}

And I'd like to deploy (or activate/desactivate) this aspect. This style of programming have some advantages: it's simple for the application programmer (not the application server programmer) and decouples application code from application server (it encapsulates dependencies in MyTraceService). Perhaps someone knows another way of doing this.

Of course it should be perfect if I could have activated several trace services, one per each application or J2EE module, at the same time.

I know that these are advanced topics and not everyday programming but I think they are important if we want AspectJ to be used to build servers, containers and frameworks.

Thanks for your patience :-)

Enrique J. Amodeo Rubio


Ron Bodkin wrote:

Indeed, enabling or disabling an aspect is a crosscutting concern. You can *almost* write a general-purpose aspect that allows you to dynamically enable or disable other aspects. It's easy to do this for arbitrary before or after advice, but the problem arises if you'd like to disable around advice. If you don't proceed with around advice, it skips the original method... I've included an example aspect below that works if your dynamic aspects don't use around advice.

 

We could generalize AspectJ a little bit to allow this aspect to enable and disable around advice too: we could make proceed a closure on JoinPoint and add some additional context to JoinPoint for advice execution: a field advisedJoinPoint. Then we could disable around advice with: thisJoinPoint.getAdvisedJoinPoint.getProceed().run(args)

 

It would also be nice if target for adviceexecution were bound to the currently running object (this) at the advised join point. The main question in my mind is whether there are compelling use cases to justify the extra complexity of this idea.

 

/**
 * This aspect automates enabling and disabling of other aspects at runtime
 * Any aspect that implements the marker interface DynamicAspect will be
 * able to be enabled or disabled dynamically at runtime.
 *
 * It's also easy to use this style of code to support configuring the aspect
 * on a per-instance basis: keep a set of deployed objects, and check if
 * this is in the set of deployed objects...
 *
 */
public aspect AspectManagement {
    private boolean DynamicAspect.enabled;

    public DynamicAspect.setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    around() : adviceexecution() && within(DynamicAspect+) {

        // could check for around advice by looking at the generated name in the signature
        if (enabled) {
           proceed();
        }
    }

    // can expose DynamicAspect for JMX...

    /**
     * This advice makes it an error to call any method on a disabled aspect.
     */
    around() : (execution(* *(..)) || execution(* new(..))) && within(DynamicAspect+) {
        if (enabled) {
            proceed();
        } else {
                 throw new UnsupportedOperationException("calling a method on a disabled aspect.");
        }

    }

}

 

Ron Bodkin

Chief Technology Officer

New Aspects of Software

o: (415) 824-4690

m: (415) 509-2895

 

 

------------Original Message------------

From: Adrian Colyer <adrian_colyer@xxxxxxxxxx>

To: aspectj-users@xxxxxxxxxxx

Date: Wed, Mar-31-2004 4:20 AM

Subject: Re: [aspectj-users] Incremental and runtime weaving support ?


Forgive the long answer, but I think it is worth discussing some of the options here, since many people are unaware of what AspectJ can do in this regard.

First of all, AspectJ has been able to support *load-time* weaving since the 1.1 release, and several folks have written weaving classloaders that exploited that fact. What we didn't do, was make it especially easy to exploit those load-time weaving capabilities. AspectJ 1.2 will ship with a new sample script in the examples directory, "aj"that will launch any Java application using load-time weaving of aspects from the ASPECTPATH environment variable ("aj" is to "ajc" as "java" is to "javac"). In addition, there is a weaving class loader shipped in the tools jar, and an adaptor that makes it easy to plug load-time weaving into an existing class-loader hierarchy. You can get many of the same benefits of arbitrary run-time weaving by combining load-time weaving with class recycling - and indeed most middleware systems support application re-loading to pick up changes at runtime by using custom classloaders.

Whether you weave at load-time or before, there are also a bunch of things you can do with aspects that give you a high degree of runtime dynamicity:

Simplest of all is the aspect that can be turned on or off at runtime - this can be made very efficient indeed following the pattern

public aspect DoSomethingInteresting {

  private static boolean isEnabled = false;

  public static void setEnabled(boolean turnMeOn) {
    this.isEnabled = turnMeOn;
  }

 pointcut isEnabled() : if(isEnabled);

 // regular advice goes here, e.g.
 before() : someInterestingJoinPoint() && isEnabled() {
   // here we go...
 }

}

You can then enable or disable the aspect behavior at runtime using the following snippet:

DoSomethingInteresting.setEnabled(true);

You can follow the same basic pattern for aspects that are pertarget, percflow etc. by making the isEnabled and setEnabled members non-static, and using

DoSomethingInteresting.aspectOf(x).setEnabled(true);


Using the per-clauses you can also easily get a whole additional range of runtime behaviours, for example the following aspect lets you decide on a pertarget basis whether or not the aspect behaviour should be enabled (strictly, whether an aspect instance should be created).

public aspect DoSomethingElseInteresting pertarget(candidateTargetObject(Object)) {

 private static boolean enableBehaviourFor(Object o) {
   // some runtime test
 }

  pointcut candidateTargetObject(Object o) : someCalls() && target(o) && if(enableBehaviourFor(o));

  // advice etc. goes here.


}

You could imagine a similar aspect using percflow and deciding on an individual control flow basis whether to create an aspect instance or not.

Frameworks like the JBoss AOP framework only allow you to do true runtime weaving on classes that have been pre-prepared (at load-time or before) to instrument their join points (I can't speak for AspectWerkz and Prose off the top of my head). If you can accept the pre-preparation step, then AspectJ can give you an equivalent degree of runtime flexibility using a pattern like the following:

public aspect RuntimeAdviceChainExample {

   private ICommand[] adviceChain;

   public void setAdviceChain(ICommand[] adviceChain) {
     this.adviceChain = adviceChain;
   }

  // could imagine other methods that let me add, remove, reorder commands in the advice chain, omitted for brevity

  pointcut someInterestingJoinPoints() : ..... ;

  before() : someInterestingJoinPoints() {
    for (int i = 0; i < adviceChain.length; i++) {
       adviceChain[i].execute(thisJoinPoint);
    }
  }

}

I've shown a general form of the aspect - if you have known context at the set of join points of interest, and are prepared to make a custom command interface you can write more efficient advice, e.g.

after(BankAccount acc) returning : bankOperation(acc) {
    for (int i = 0; i < adviceChain.length; i++) {
       adviceChain[i].execute(acc);
    }
}

So, to summarize, you can already do a surprising amount at runtime using the existing facilities of AspectJ. Are there any strong use cases out there not supported by one of the above mechanisms?

-- Adrian
Adrian_Colyer@xxxxxxxxxx


aspectj-users-admin@xxxxxxxxxxx wrote on 31/03/2004 11:59:27:

> Hi,
> you can try dynamic AOP tools, like:
> PROSE (http://prose.ethz.ch/)
> Aspectwerkz (http://aspectwerkz.codehaus.org/)
> JBoss/AOP
>
> cheers
>
> paolo
>
>
> On Wed, 31 Mar 2004 12:26:13 +0200, Enrique J. Amodeo Rubio
> <eamodeorubio@xxxxxxxxxxxxxx> wrote:
>
> > Hi everybody,
> >
> > I had a talk with my boss about the limits of  AspectJ and some
> questions appeared.
> > Is there any plans about supporting runtime (not load time)
> weaving? And for incremental weaving? I have read about -Xreweavable
> and I wonder if this option could made feasible to support these
> features in the future. For runtime weaving I mean the ability to
> load and weave an aspect during the execution of a program in a
> similar way that you can load a class and use them. I think that
> incremental weaving is necessary in order to achieve a good
> performance. Of course some AspectJ features like introduction could
> not support this (but I can live without them). I understand that
> JVM technology can put limitations on these topics.
> >
> > Perhaps this subject has been discussed in another mail threads.
> If so please send me some links since I can't  find them.
> >
> > Thanks,
> >
> > Enrique J. Amodeo Rubio
> >  _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top