Skip to main content

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

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




Back to the top