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


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

Jim and Erik had a paper at the AOSD conference that discussed the performance of if(enabled) (it's pretty good) - see http://hugunin.net/papers/aosd-2004-cameraReady.pdf.

AspectJ 1.2 also has a new option -XlazyTjp (guess what that does ;) ) which makes the performance much much better in the cases where advice uses the non-static portions of thisJoinPoint.

On the point of changing a service implementation, the following sample code shows a neat way to do this using proceed (it implements a per-instance delegate, other variations on the theme may not need this level of complexity).

/**
 * @author colyer
 * Runtime delegation configured on a per-instance
 * basis.
 */
public class SimpleDelegationExample {

        interface ICanDoIt {
                void doIt();
        }

        static class CanDoIt implements ICanDoIt {
                private String msg;
                public CanDoIt(String s) {
                        this.msg = s;
                }
                public void doIt() {
                        System.out.println(msg);
                }
         }
         

        public static void main(String[] args) {
                ICanDoIt a = new CanDoIt("I can do it");
                ICanDoIt b = new CanDoIt("You can do it too");
                a.doIt();
                b.doIt();
                ICanDoIt c = new CanDoIt("We really should do this more often");
                // try running this program with and without the next two lines commented out to observe the difference
                DelegationMgr mgrForA = DelegationMgr.aspectOf(a);
                mgrForA.setDelegate(c);
                a.doIt();
        }
       
        private static aspect DelegationMgr pertarget(canDo()){
                private ICanDoIt delegate;
                public void setDelegate(ICanDoIt delegate) {
                        this.delegate = delegate;
                }
                               
                pointcut delegationScope(ICanDoIt delegate) :
                  execution(* ICanDoIt.*(..)) && this(delegate);
                 
                Object around(ICanDoIt d) : delegationScope(d) {
                        return proceed(delegate != null ? delegate : d);  
                }
        }
}

-- Adrian
Adrian_Colyer@xxxxxxxxxx


aspectj-users-admin@xxxxxxxxxxx wrote on 31/03/2004 15:46:51:

> 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