[
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