[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-dev] Possible Library Aspect: Aspect Error Containment

Hi Ron

To select adviceexecution() you can use an annotation @AdviceToAdvise
(or whatever) and then compose it like:
adviceexecution() && within(.....) && @annotation(AdviceToAdvise)

I think it will be possible to further use the @AJ annotation and the
meta aspect protocol to match f.e. only before advice etc (&&
@annotation(Before)) in the upcoming versions.

As per matching on signature, this sounds fragile to me, since those
can change often when you are changing the formal bindings. What is
the use case for this one ?

Alex


On 5/2/05, Ron Bodkin <rbodkin@xxxxxxxxxxxxxx> wrote:
> Hi Alex,
> 
> You are right, it *does* inline this around advice ... Thanks for clarifying
> this! That's good news...
> 
> I misunderstood the assembly code output of what the compiler was doing... I
> saw that it was calling the method with the around closure argument, but I
> now see that it passes a *null* argument for the closure when inlining the
> advice.
> 
> I'd be interested in thoughts on better matching signatures for
> adviceexecution too...
> 
> 
> -----Original Message-----
> From: aspectj-dev-bounces@xxxxxxxxxxx
> [mailto:aspectj-dev-bounces@xxxxxxxxxxx] On Behalf Of Alexandre Vasseur
> Sent: Monday, May 02, 2005 1:03 AM
> To: AspectJ developer discussions
> Subject: Re: [aspectj-dev] Possible Library Aspect: Aspect Error Containment
> 
> Ron,
> Are you sure we don't inline around advice when proceed() occurs in a
> try catch block ? I think we do.
> Alex
> 
> On 4/28/05, Ron Bodkin <rbodkin@xxxxxxxxxxxxxx> wrote:
> > Hi All,
> >
> > I've written an aspect that will prevent other aspects (typically
> auxiliary
> > ones) from raising exceptions that interrupt core program logic. The basic
> > idea is that if the function of the aspect fails, you want to log it, but
> > not block the core system from functioning. This is useful for auxiliary
> > aspects like monitoring (what I'm working on), auditing, logging, and
> > tracing but certainly not for applications like security or caching. This
> > aspect came to mind from a discussion with the NearInfinity developers and
> I
> > recently found the first case where I needed it on my project.
> >
> > Here's the core of the aspect (somewhat simplified):
> >
> > public aspect ErrorContainment {
> >   pointcut scope() : within(Foo);
> >
> >   Object around() : adviceexecution() && scope() { //&&
> if(((AdviceSignature
> >         thisJoinPointStaticPart.getSignature()).getReturnType() ==
> > void.class){
> >     try {
> >         return proceed();
> >     } catch (Error e) {
> >         handle(e);
> >     } catch (RuntimeException rte) {
> >         handle(rte);
> >     }
> >     return null; // will only be void
> >   }
> >   void handle(Throwable t) {     // swallows
> >     System.err.println("throwable "+t);
> >   }
> > }
> >
> > Now, I've run into a few interesting issues in doing this.
> >
> > The short summary is that optimizing the weaver to inline this around
> advice
> > would make this aspect much more useful, and it would be a bit cleaner if
> > AspectJ supported signature matching for adviceexecution. In more detail:
> >
> > * The 1.5.0 M2 compiler won't inline the use of this advice, which makes
> it
> > too expensive to use for my intended application. It certainly doesn't fit
> > the design case of around advice that won't be inlined "If there was a
> > proceed call in a nested type the weaver must assume that the call to
> > proceed is closed over." (from Hugunin & Hilsdale, "Advice Weaving in
> > AspectJ"). A little testing suggests to me that a closure is also created
> if
> > there's a catch block around the proceed, which seems like a good area to
> > optimize for any kind of error handling aspect.
> > * I don't believe there's any way to write this aspect to work correctly
> for
> > around advice with AspectJ 1.5 as planned. The problem is that you can't
> > proceed with the underlying proceed if there's an error before it
> occurs.(*)
> > * Failing that, I wanted to apply the advice to only before or after
> advice.
> > However, there's no portable way to detect the type of advice (one could
> > parse the generated method name but that's clearly fragile). Failing that,
> > to only apply this advice to advice that returns void, you have to execute
> > the (commented out) test which translates into some runtime overhead
> > (dispatching to an if-test method), and you still have to use the
> > polymorphic return of Object from the advice, since the compiler doesn't
> > know it can only return void.
> > This is a good case where having a *signature* inside adviceexecution
> would
> > be useful, e.g., adviceexecution(before), or adviceexecution(void
> > around(int)) As an aside, this would also be a natural way to match
> > annotations on adviceexecution (presumably it's currently done using
> > @annotation?)
> >
> > Ron
> >
> > (*) In general, of course, you can't really define how this should work
> for
> > around advice. But for the common case of around advice that does
> something,
> > always proceeds with the original arguments, and then does something else,
> > it would be nice to be able to write this. If there were a proceeding join
> > point, then you could write something like this:
> >
> > aspect ErrorContainment {
> >   private ThreadLocal<Boolean> hasProceeded;
> >   private ThreadLocal<ProceedClosure> proceedInstance;
> >
> >   Object around() : adviceexecution(* around(..)) && scope() {
> >     try {
> >         hasProceeded.set(false);
> >         proceedInstance.set(thisJoinPoint.getProceedClosure());
> >         return proceed();
> >     } catch (RuntimeException e) {
> >         try {
> >             handleError(e);
> >         } finally {
> >             if (!hasProceeded.get()) {
> >                 return thisJoinPoint.getProceedClosure(); // this would
> > force not inlining ...
> >             }
> >         }
> >     }
> >   }
> >   before() : proceeding() && scope() {
> >      if (this.equals(proceedInstance.get())) {
> >          hasProceed.set(true);
> >      }
> >   }
> > ...
> >
> > In practice, I don't think handling this case for around advice is very
> > important. My goal is to use only before and after advice wherever
> possible
> > and to manually add error containment to that where required...
> >
> > Ron Bodkin
> > Chief Technology Officer
> > New Aspects of Software
> > w: (415) 824-4690
> >
> > _______________________________________________
> > aspectj-dev mailing list
> > aspectj-dev@xxxxxxxxxxx
> > https://dev.eclipse.org/mailman/listinfo/aspectj-dev
> >
> _______________________________________________
> aspectj-dev mailing list
> aspectj-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-dev
> 
> _______________________________________________
> aspectj-dev mailing list
> aspectj-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-dev
>