Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-dev] Re: after() and around() advice does not work on handler join poi nts.

I have a similar thought. Could something like following be 
implemented:
1. When ajc is supplied the source code, it annotates the byte code
   generated such that weaving phase will know where exaclty
   to instrucment the advice.
2. If weaver sees the annotations, it performs weaving as per
   language semantics. However, if it does not find annotation
   (because the code was compiled with, say, javac), it issues
   compiler-limiation warning (as it does right now.).

BTW, thanks Jim for your detailed reply.

-Ramnivas

--- Ron Bodkin <rbodkin@xxxxxxxxxxx> wrote:
> This also raises the question of whether it's better to implement
> AspectJ constructs that are only unambiguous at a bytecode level, or
> whether it makes sense to define some that only work when source code
> is
> available.
> 
> In the final code example you gave, it might also be important to the
> developer that the after returning advice for the handler ran before
> the
> call to foo... whereas in the second it might be important for it to
> run
> after. So I don't think any bytecode-only strategy will always
> generate
> the 
> correct results.
> 
> -----Original Message-----
> From: aspectj-dev-admin@xxxxxxxxxxx
> [mailto:aspectj-dev-admin@xxxxxxxxxxx] On Behalf Of
> Jim.Hugunin@xxxxxxxx
> Sent: Tuesday, March 04, 2003 12:03 PM
> To: aspectj-dev@xxxxxxxxxxx
> Subject: [aspectj-dev] Re: after() and around() advice does not work
> on
> handler join poi nts.
> 
> I'm replying to this on the dev list since I think it's an
> interesting
> discussion.  I'll put some summary back into the bug database when
> the
> discussion is done.
> 
> Ramnivas wrote (to the bug database): 
> > This bug (or compiler limitation) is seen in 1.1beta4. The same
> program
> > works fine in 1.0.6.
> > 
> > Test program:
> > public class Test {
> >     public static void main(String[] args) {
> > 	try {
> > 	    foo();
> > 	} catch (NullPointerException ex) {
> > 
> > 	}
> >     }
> > 
> >     public static void foo() {
> >     }
> > }
> > 
> > aspect AfterHandlerAspect {
> >     after() : handler(NullPointerException) {
> > 	System.out.println("Thrown NullPointerException");
> >     }
> > }
> > 
> > F:\aspectj\bugs\1.1\b4\after-handler>ajc *.java
> > Only before advice is supported on handler join points (compiler
> > limitation)
> > Only before advice is supported on handler join points (compiler
> > limitation)
> > 
> > 2 warnings
> > 
> > Indetical error is issued if I use around() advice instead of
> after().
> > 
> > Why is this compiler limitation? This prevents implementing
> crosscutting
> > that relies on checking the state of thrown exception by a handler
> block.
> 
> This limitation is a result of weaving into bytecodes instead of
> source
> code.  It is either hard or impossible to reliably find the end of an
> exception handler in bytecode.  We decided that it would be better to
> make this unimplemented in 1.1 rather than come up with an rushed
> definition of the end of a handler block that we would be forced to
> live
> with forever after.  Here are two quick examples of where this is
> easy
> and where it's hard/impossible.
> 
> Your Test class above produces the following bytecode (with javac):
> 
> Method void main(java.lang.String[])
>    0 invokestatic #2 <Method Test.foo()V>
>    3 goto 7
>    6 astore_1
>    7 return
> Exception table:
>    from   to  target type
>      0     3     6   <Class java.lang.NullPointerException>
> 
> This is an example of a common pattern that would let us find the end
> of
> most exception handlers.  Just before the handler block there is a
> goto
> that goes to the instruction just past the end.  Checking for this
> pattern would let us handle 99% of actual exception handlers. 
> However,
> what should ajc do when this pattern isn't present or when it's
> wrong?
> 
> Consider this bytecode:
> 
> Method void bar()
>    0 invokestatic #2 <Method Test.foo()V>
>    3 return
>    4 astore_0
>    5 invokestatic #2 <Method Test.foo()V>
>    8 return
> Exception table:
>    from   to  target type
>      0     4     4   <Class java.lang.NullPointerException>
> 
> It could be produced from either of these two programs:
> A:  public static void bar() {
>       try {
> 	  foo();
> 	  return;
> 	} catch (NullPointerException ex) {
> 	  foo();
> 	}
>     }
> OR
> B:  public static void bar() {
>       try {
> 	  foo();
> 	  return;
> 	} catch (NullPointerException ex) {
> 	}
> 	foo();
>     }
> 
> So, should we consider the foo() to be inside of the catch block or
> not?
> 
> You might be able to make the argument that in a case like this it's
> reasonable to treat the call to foo() as effectively part of the
> catch
> block since it can only be called if an exception is caught. 
> However,
> it's also easy to see how this might be very confusing to a
> programmer
> who wrote B.
> 
> I suspect that this issue could be resolved with some hard thought
> and
> analysis of all the possible edge cases; however, this feature was
> not
> deemed important enough to delay the 1.1 release until that analysis
> could be done.
> 
> -Jim
> _______________________________________________
> aspectj-dev mailing list
> aspectj-dev@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-dev
> 
> _______________________________________________
> aspectj-dev mailing list
> aspectj-dev@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-dev


__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/


Back to the top