Bug 33636 - after() and around() advice does not work on handler join points.
Summary: after() and around() advice does not work on handler join points.
Status: REOPENED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows NT
: P5 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords: info
Depends on:
Blocks:
 
Reported: 2003-03-02 20:08 EST by Ramnivas Laddad CLA
Modified: 2009-08-30 02:51 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ramnivas Laddad CLA 2003-03-02 20:08:25 EST
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.
Comment 1 Jim Hugunin CLA 2003-03-05 16:49:29 EST
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
Comment 2 Jim Hugunin CLA 2003-06-04 13:14:42 EDT
marking as info because this clarifies a long-standing compiler limitation 
reagarding around advice on handlers and explains a new limitation in 1.1 
regarding after advice on handlers
Comment 3 Eclipse Webmaster CLA 2009-08-30 02:51:19 EDT
LATER/REMIND bugs are being automatically reopened as P5 because the LATER and REMIND resolutions are deprecated.