Bug 86452 - compiler cannot compile class with @AfterReturning
Summary: compiler cannot compile class with @AfterReturning
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 1.5.0 M3   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-24 06:10 EST by Alexandre Vasseur CLA
Modified: 2005-05-10 11:54 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 Alexandre Vasseur CLA 2005-02-24 06:10:57 EST
The compiler cannot compile Java 5 classes annotated with a @AfterReturning

C:\Temp\ajcSandbox\ajcTest52857.tmp\ataspectj\AfterXTest.java:86:0::0 Syntax
error on token "@", NameOrAj expected after this token
	error at @AfterReturning(returned="ret", pointcut="execution(int
ataspectj.AfterXTest.dupPos(..)) && args(arg)")
 ^^^^^^




@Target(ElementType.METHOD)
public @interface AfterReturning {

    /**
     * The pointcut expression where to bind the advice
     */
    String value() default "";

    /**
     * The pointcut expression where to bind the advice, overrides "value" when
specified
     */
    String pointcut() default "";

    /**
     * The name of the argument in the advice signature to bind the returned
value to
     */
    String returned() default "";
}



public class AfterXTest extends TestCase {

    static StringBuffer s_log = new StringBuffer();
    static void log(String s) {
        s_log.append(s).append(" ");
    }

    public static void main(String[] args) {
        TestHelper.runAndThrowOnFailure(suite());
    }

    public static junit.framework.Test suite() {
        return new junit.framework.TestSuite(AfterXTest.class);
    }

    public int dupPos(int i) throws NoSuchMethodException {
        if (i > 0)
            return i*2;
        else
            throw new NoSuchMethodException("arg is negative");
    }

    public void testAfterReturningAndThrowing() {
        AfterXTest me = new AfterXTest();

        try {
            s_log = new StringBuffer();
            int dup2 = me.dupPos(2);
            // see after advice precedence here..
            //TODO really weird after finally comes first
            // see BcelWeaver fix on sorting of shadowMungerList
            //assertEquals("after after2- 2 4 afterRet- 2 ", s_log.toString());
            assertEquals("afterRet- 2 after2- 2 4 after ", s_log.toString());
        } catch (Exception e) {
            fail("Should not fail " + e.toString());
        }

        s_log = new StringBuffer();
        try {
            int dupm2 = me.dupPos(-2);
            fail("should not be reached");
        } catch (NoSuchMethodException e) {
            //TODO really weird after finally comes first
            // see BcelWeaver fix in sorting of shadowMungerList
            assertEquals("after afterThrowing afterThrowing3- [arg is negative]
", s_log.toString());
        }
    }



    @Aspect
    public static class TestAspect {

        @AfterReturning("execution(int ataspectj.AfterXTest.dupPos(..)) &&
args(arg)")
        public void afterRet(int arg) {
            log("afterRet-");
            log(""+arg);
        }

        @AfterReturning(returned="ret", pointcut="execution(int
ataspectj.AfterXTest.dupPos(..)) && args(arg)")
        public void after2(int arg, int ret) {//CORRECT
        //public void after2(int ret, int arg) {//INCORRECT
            log("after2-");
            log(""+arg);
            log(""+ret);
        }

        @After("execution(int ataspectj.AfterXTest.dupPos(..))")
        public void after() {
            log("after");
        }

        @AfterThrowing("execution(int ataspectj.AfterXTest.dupPos(..))")
        public void afterThrowing(JoinPoint jp) {
            log("afterThrowing");
        }

        // formal binding is mandatory in AJ
        //@AfterThrowing(throwned="java.lang.RuntimeException",
pointcut="execution(int alex.test.ReturnAndThrowHelloWorld.dupPos(..))")
        //public void afterThrowing2() {
        @AfterThrowing(throwned="e", pointcut="execution(int
ataspectj.AfterXTest.dupPos(..))")
        public void afterThrowing2(RuntimeException e) {
            fail("should not be bounded");
        }

        @AfterThrowing(throwned="e", value="execution(int
ataspectj.AfterXTest.dupPos(..))")
        public void afterThrowing3(NoSuchMethodException e) {
            log("afterThrowing3-");
            log("["+e.getMessage()+"]");
        }
    }

}
Comment 1 Adrian Colyer CLA 2005-02-24 09:52:58 EST
I just tried out the following simpler program with the Eclipse 3.1 M4 Java
compiler (no AspectJ in sight) and it also fails.

public class SomeClass {

    @AfterReturning("execution(int ataspectj.AfterXTest.dupPos(..)) && args(arg)")
    public void afterRet(int arg) {
//        log("afterRet-");
//        log(""+arg);
    }

    @AfterReturning(returned="ret", pointcut="execution(int
ataspectj.AfterXTest.dupPos(..)) && args(arg)")
    public void after2(int arg, int ret) {//CORRECT
//    public void after2(int ret, int arg) {//INCORRECT
//        log("after2-");
//        log(""+arg);
//        log(""+ret);
    }
}

(in this case with an internal compiler exception). If you comment out the
"returned="ret"," part of the second annotation it gets through. I'll download
M5 soon and see if its been fixed in that version of the JDT, otherwise we
should raise a bug against them. We will pick up the fix in AspectJ on our next
JDT compiler integration phase. There may be a workaround I can do in AspectJ in
the meantime...
Comment 2 Alexandre Vasseur CLA 2005-02-25 11:44:22 EST
tested with a small app on 3.1M5a and Sun 1.5.0_01 and seems ok
will test with the AJ5 branch on monday

how will we deal with the AJ jdt update ?
(is that needed for AJC to compile that ?, if so, how that is dealt, etc)

Comment 3 Andrew Clement CLA 2005-02-25 11:56:06 EST
yes, the 3.1M5a version of the compiler will need to be integrated to fix this
problem (based on what you've just tried).

Normally we migrate to a new JDT compiler version once or twice per Eclipse
version (I think we went to M6 and final for Eclipse 3.0).  We don't move with
every milestone version of eclipse.  On this occassion we might move to the M5
one as it addresses this and no doubt some of the related annotation problems
we've been seeing.  The three way branch merge for integrating a new compiler is
horrible and usually left to Adrian :)
Comment 4 Adrian Colyer CLA 2005-03-23 09:49:03 EST
i will update to the latest JDT compiler as the first thing  we do in aj5m3,
this should fix this problem...
Comment 5 Alexandre Vasseur CLA 2005-04-27 03:48:28 EDT
side note: we spotted thanks to Adrian that inner class of @Aspect annotated
class gets the @Aspect annotation on them as well
This is a bug in Java 1.5 (old version) that sneaks in the JDT but not in JDT of
3.1M6 currently beeing integrated

Comment 6 Alexandre Vasseur CLA 2005-05-10 11:54:07 EDT
fixed by Adrian, test case for @AJ ok