Bug 172107 - Problem with set pointcut and inherited fields
Summary: Problem with set pointcut and inherited fields
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: LTWeaving (show other bugs)
Version: 1.5.3   Edit
Hardware: PC Linux
: P3 major (vote)
Target Milestone: 1.5.4   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-30 00:08 EST by Szymon Wrozynski CLA
Modified: 2012-04-03 15:59 EDT (History)
3 users (show)

See Also:


Attachments
AJDT project with simple example illustrating this bug (2.04 KB, application/zip)
2007-04-27 11:11 EDT, Timothy Halloran CLA
no flags Details
Patch fixing this bug (2.36 KB, patch)
2007-04-28 02:19 EDT, Timothy Halloran CLA
aclement: iplog+
Details | Diff
Test case for this patch (to "tests" module) (4.14 KB, patch)
2007-04-30 12:21 EDT, Timothy Halloran CLA
aclement: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Szymon Wrozynski CLA 2007-01-30 00:08:26 EST
Consider following example:

class A {
protected int i;
}

class B extends A {
public B() {
i = 15; // ! set without explicit 'super' keyword, it's ok for the compiler
}

....
in an aspect:

after(): set (* *) {after setting of any field
FieldSignature fs = (FieldSignature) thisJoinPoint.getSignature();
Field f = fs.getField(); // it's null for the join point above
assert (f != null); //false
}

It's strange that the implicit setting of a protected field cause fs.getField() to return null whereas explicit setting with keyword super do not.

class B extends A {
public B() {
super.i = 15; // it's ok for the pointcut (but it's rendundant)
}
Comment 1 Timothy Halloran CLA 2007-04-26 19:55:34 EDT
Yes, I'm seeing this behaviour as well. (thanks for the good report as I was scratching my head about what caused getField() to return null).

I can't figure out where the getField() code is within the source as I suspect that the implementation uses reflection and that it should be walking up the superclass chain calling getDeclaredFields() as well as looking at all interfaces (for static final fields).  This should be easy to fix...any pointers as to where to start?

Also the reflection libraries don't do too well on the "length" field of arrays...I'm not sure if that is handled correctly either.

Thanks!
Comment 2 Timothy Halloran CLA 2007-04-26 19:58:29 EDT
OK, at least in my large test case (running JEdit with aspects on) I only get nulls from getField() for "set" pointcuts never "get" pointcuts...this is odd?
Comment 3 Timothy Halloran CLA 2007-04-27 11:11:12 EDT
Created attachment 65217 [details]
AJDT project with simple example illustrating this bug

Here is a simple example that shows this problem.  The output I get from the problem using 1.5.3 and the latest development build (aspectj-DEVELOPMENT-20070228132200.jar) is:

11
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 18
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 19
22
11
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 25
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 26
22
56

I have not tried the program on HEAD from CVS (I can't get it to build due to my ignorance and inexperience :-)
Comment 4 Timothy Halloran CLA 2007-04-27 22:31:14 EDT
Ok uncommenting the println() on lines 141 and 143 in SignatureImpl.java (within the String extractString(int n) method) I get (in the attached test above) the snippet:

getField() called
2:  from 4-prot-B-int-
    B
1:  from 4-prot-B-int-
    prot
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 18

The weaving is passing a string representation of the field information, however, it is wrong about the declaring class--it is not "B" but "A" thus the null from getField() which uses getDeclaredField(String name) on the declaringClass.

The whole output is:

getField() called
2:  from 4-prot-A-int-
    A
1:  from 4-prot-A-int-
    prot
getField() called
2:  from 4-protS-A-java.lang.String-
    A
1:  from 4-protS-A-java.lang.String-
    protS
getField() called
2:  from 19-out-java.lang.System-java.io.PrintStream-
    java.lang.System
1:  from 19-out-java.lang.System-java.io.PrintStream-
    out
getField() called
2:  from 4-protS-A-java.lang.String-
    A
1:  from 4-protS-A-java.lang.String-
    protS
getField() called
2:  from 4-prot-A-int-
    A
1:  from 4-prot-A-int-
    prot
11
getField() called
2:  from 4-prot-B-int-
    B
1:  from 4-prot-B-int-
    prot
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 18
getField() called
2:  from 4-protS-B-java.lang.String-
    B
1:  from 4-protS-B-java.lang.String-
    protS
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 19
getField() called
2:  from 19-out-java.lang.System-java.io.PrintStream-
    java.lang.System
1:  from 19-out-java.lang.System-java.io.PrintStream-
    out
getField() called
2:  from 4-protS-A-java.lang.String-
    A
1:  from 4-protS-A-java.lang.String-
    protS
getField() called
2:  from 4-prot-A-int-
    A
1:  from 4-prot-A-int-
    prot
22
getField() called
2:  from 0-def-A-int-
    A
1:  from 0-def-A-int-
    def
getField() called
2:  from 0-defS-A-java.lang.String-
    A
1:  from 0-defS-A-java.lang.String-
    defS
getField() called
2:  from 19-out-java.lang.System-java.io.PrintStream-
    java.lang.System
1:  from 19-out-java.lang.System-java.io.PrintStream-
    out
getField() called
2:  from 0-defS-A-java.lang.String-
    A
1:  from 0-defS-A-java.lang.String-
    defS
getField() called
2:  from 0-def-A-int-
    A
1:  from 0-def-A-int-
    def
11
getField() called
2:  from 0-def-B-int-
    B
1:  from 0-def-B-int-
    def
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 25
getField() called
2:  from 0-defS-B-java.lang.String-
    B
1:  from 0-defS-B-java.lang.String-
    defS
BUG: set FieldSignature#getField()==null in ReadWriteAJBug172107.java at line 26
getField() called
2:  from 19-out-java.lang.System-java.io.PrintStream-
    java.lang.System
1:  from 19-out-java.lang.System-java.io.PrintStream-
    out
getField() called
2:  from 0-defS-A-java.lang.String-
    A
1:  from 0-defS-A-java.lang.String-
    defS
getField() called
2:  from 0-def-A-int-
    A
1:  from 0-def-A-int-
    def
22
getField() called
2:  from 19-out-java.lang.System-java.io.PrintStream-
    java.lang.System
1:  from 19-out-java.lang.System-java.io.PrintStream-
    out
56
Comment 5 Timothy Halloran CLA 2007-04-27 23:07:28 EDT
More digging on this problem and I've discovered that the weaver works if the compiler is set at 1.3.  The bug appears if the compiler is 1.4 or 1.5.

I'm guessing this is a bug in the weaver.  Something about resolving the type changed in the byte code format between 1.3 and 1.4.  It is odd that it works ok for "get" but not for "set".  Could this be a BCEL or ASM bug?
Comment 6 Timothy Halloran CLA 2007-04-27 23:20:45 EDT
I'm pretty sure that this problem is occurring because bug 109728 only fixed "get" and not "set"
Comment 7 Timothy Halloran CLA 2007-04-28 02:19:56 EDT
Created attachment 65309 [details]
Patch fixing this bug

Fixed...here is the patch.  It passes the entire "RunTheseBeforeYouCommitTests" on HEAD.  I haven't figured out how to add my test case.  I'll do that tomorrow and post that patch as well.
Comment 8 Timothy Halloran CLA 2007-04-30 12:21:00 EDT
Created attachment 65397 [details]
Test case for this patch (to "tests" module)

Here is a test case for the patch above.  It fails without the above patch.
Comment 9 Matt Chapman CLA 2007-05-14 07:11:15 EDT
Can this go into AJDT 1.5?
Comment 10 Andrew Clement CLA 2007-05-21 07:55:15 EDT
testcase and patch committed.  When is 1.5 scheduled to finally ship matt? probably can get it in there.
Comment 11 Matt Chapman CLA 2007-05-21 14:08:19 EDT
I've picked this up in AJDT, just in time for the 3.3 release:
1.5.0.200705211141 for Eclipse 3.3M7/RC1 includes AspectJ version 1.5.4.200705211336
Comment 12 Andrew Clement CLA 2007-10-26 06:22:24 EDT
from those comments, this should be closed as fixed.