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.

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



Back to the top