Bug 73856 - ITD on inner class: missing accessor method
Summary: ITD on inner class: missing accessor method
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Linux
: P5 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-09-14 07:05 EDT by Oege de Moor CLA
Modified: 2007-10-23 06:21 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oege de Moor CLA 2004-09-14 07:05:30 EDT
The program below compiles fine with ajc (dev version of Wednesday Sep 8, 2004
at 19:18:04 GMT), but at runtime we get

Exception in thread "main" java.lang.NoSuchMethodError: A$B.access$0(LA$B;)LA;
        at Aspect$1$C.bar(MissingAccessor.java:12)
        at Aspect.ajc$interMethod$Aspect$A$B$foo(MissingAccessor.java:14)
        at A$B.ajc$interMethodDispatch2$$foo(MissingAccessor.java)
        at Aspect.ajc$interMethodDispatch1$Aspect$A$B$foo(MissingAccessor.java)
        at MissingAccessor.main(MissingAccessor.java:22)

It should print 1024.


-------------------------------------------------------------

class A {
        int x = 1;
        class B { int x = 10; }
        B b = new B();
}
aspect Aspect {
        static int x = 100;
        static int y = 3;
        int A.B.foo() {
                class C {
                        int x = 1000;
                        int bar() {return x + A.this.x;}
                }
                return this.x + (new C()).bar() + y;
        }
}

public class MissingAccessor {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b.foo());
    }
}
Comment 1 Adrian Colyer CLA 2005-08-26 11:11:31 EDT
investigate for M4
Comment 2 Andrew Clement CLA 2005-09-30 05:57:13 EDT
What a realistic program ;)

Here's a shorter version that still fails:

class A {
  int x = 1;
  class B { }
  B b = new B();
}
aspect Aspect {
  int A.B.foo() {
     class C {
        int bar() { return A.this.x;}
     }
     return new C().bar();
  }
}

public class MissingAccessor {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b.foo());
    }
}

it may not print 1024 but it fails with the same error.  Given that the
reference to the access$0 method is generated OK, my suspicion was that it was a
type order processing thing, and indeed, if you move 'A' to after the aspect,
then it runs fine:

aspect Aspect {
  int A.B.foo() {
     class C {
        int bar() { return A.this.x;}
     }
     return new C().bar();
  }
}

class A {
  int x = 1;
  class B { }
  B b = new B();
}

public class MissingAccessor {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.b.foo());
    }
}

now, what on earth we can do about that, hmmmmmmmmm

Comment 3 Andrew Clement CLA 2005-10-03 04:05:38 EDT
putting on my TODO list, testcase added to CVS.
Comment 4 Adrian Colyer CLA 2005-10-28 07:55:35 EDT
moving to 1.5.1 - not because it's not important, but because it's very seldom seen in the wild and we 
need to close out the release.
Comment 5 Eduardo Piveta CLA 2006-01-11 00:13:58 EST
(In reply to comment #2)

I don't know it if might help, but I tried to narrow the example down to a single unit:

aspect Aspect {
   class B {}
   int B.foo() {
      class C {
         int bar() { return Aspect.this.hashCode(); }
      }
      return new C().bar();
   }
   public static void main(String[] args) {
      System.out.println(aspectOf().new B().foo());
   }
}

The exception raised is almost the same:
----------------------------------------------------------------------
Exception in thread "main" java.lang.NoSuchMethodError: Aspect$B.access$0(LAspect$B;)LAspect;
	at Aspect$1C.bar(Aspect.aj:5)
	at Aspect.ajc$interMethod$Aspect$Aspect$B$foo(Aspect.aj:7)
	at Aspect$B.ajc$interMethodDispatch2$$foo(Aspect.aj:1)
	at Aspect.ajc$interMethodDispatch1$Aspect$Aspect$B$foo(Aspect.aj)
	at Aspect.main(Aspect.aj:10)
----------------------------------------------------------------------
Note that (in line 3 of exception) The mangled name itmd is   'Aspect.ajc$interMethod$Aspect$Aspect$B$foo'.

If the line:

return Aspect.this.hashCode();

is changed to: 

return this.hashCode();

the code works (whatever this actually means...).
Comment 6 Andrew Clement CLA 2006-01-11 04:18:44 EST
that possibly helps - thanks.  I think I know what the fix is but its a large implementation cost when there are simple workarounds...  basically the compiler doesn't get the time to add the necessary accessors so the weaver would have to do it.