Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Bizarre behavior with args pointcut

Hi Jeff -

> Is there documention saying exactly what this(), target(), ... do? The > following example would suggest they do in fact do an 'instanceof' check.

As you know, this is discussed in the semantics appendix to the
programming guide with the usual precision :)

Your comment is confusing because I basically said they do
instanceof.  But if I understand the question presented by the
code, you're asking why the first toString() call was not
picked out by target(C).

It's basically because they are different classes in your code.
Your classloader implementation is faulty (imho) because it
doesn't do a super.findClass(..)/resolve first.  Aspects aside,
you will see a ClassCastException if you do this:

    Object o = new MyLoader().findClass("CL$C").newInstance();
    out(o.toString());
    out("-----------------------------");
    Object o2 = new C() {public void f(){}};
    out(o2.toString());
    C c = (C) o;    // CCE here - different classloaders
    c = (C) o2;

Wes

P.S. - At one point in AspectJ history there was a subtlety
in the definition of these dynamic checks that meant the
semantics weren't identical to instanceof, but I don't think
it required embedded bytecode to demonstrate :)

Jeffrey D Palm wrote:
Wes Isberg wrote:

this(), target(), and args() always (act as if they) do a dynamic instance-of check on the object. The semantics are the same whether the object is bound to a variable or not. (And as per
instanceof, a null object will not match.)


Is there documention saying exactly what this(), target(), ... do? The following example would suggest they do in fact do an 'instanceof' check.

//----- begin code -----
public class CL {
  public static void main(String[] args) throws Exception {
    out(new MyLoader().findClass("CL$C").newInstance().toString());
    out("------------------------------------------------------------");
    out(new C() {public void f(){}}.toString());
  }

  static void out(Object s) {System.out.println(s);}

  public static class C {
    public C() {}
    public void f() { System.out.println("C.f"); }
  }

  static aspect A {
    before(): target(C) { out("before: " + thisJoinPoint); }
  }

  static class MyLoader extends ClassLoader {
    protected Class findClass(String name)
    throws ClassNotFoundException {
      return super.defineClass(name, Cbytes, 0, Cbytes.length);
    }
  }

  final static byte[] Cbytes = new byte[] {
    -54,-2,-70,-66,0,0,0,47,0,32,7,0,2,1,0,
    4,67,76,36,67,7,0,4,1,0,16,106,97,118,
    97,47,108,97,110,103,47,79,98,106,101,99,116,1,0,
    1,102,1,0,3,40,41,86,1,0,4,67,111,100,
    101,1,0,15,76,105,110,101,78,117,109,98,101,114,
    84,97,98,108,101,12,0,10,0,11,1,0,3,111,
    117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,
    114,105,110,116,83,116,114,101,97,109,59,9,0,13,0,
    9,7,0,14,1,0,16,106,97,118,97,47,108,97,110,
    103,47,83,121,115,116,101,109,8,0,16,1,0,3,67,
    46,102,12,0,18,0,19,1,0,7,112,114,105,110,
    116,108,110,1,0,21,40,76,106,97,118,97,47,108,
    97,110,103,47,83,116,114,105,110,103,59,41,86,10,0,
    21,0,17,7,0,22,1,0,19,106,97,118,97,47,105,
    111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,
    6,60,105,110,105,116,62,12,0,23,0,6,10,0,3,
    0,24,1,0,10,83,111,117,114,99,101,70,105,108,
    101,1,0,7,67,76,46,106,97,118,97,1,0,12,73,
    110,110,101,114,67,108,97,115,115,101,115,7,0,30,1,
    0,2,67,76,1,0,1,67,0,33,0,1,0,3,0,
    0,0,0,0,2,0,1,0,5,0,6,0,1,0,7,
    0,0,0,37,0,2,0,1,0,0,0,9,-78,0,12,
    18,15,-74,0,20,-79,0,0,0,1,0,8,0,0,0,
    10,0,2,0,0,0,10,0,8,0,10,0,1,0,23,
    0,6,0,1,0,7,0,0,0,33,0,1,0,1,0,
    0,0,5,42,-73,0,25,-79,0,0,0,1,0,8,0,
    0,0,10,0,2,0,0,0,9,0,4,0,9,0,2,
    0,26,0,0,0,2,0,27,0,28,0,0,0,10,0,1,0,1,0,29,0,31,0,9,
  };
}
//----- end code -----


This prints out:

  jpalm@Machine ~/src/aspectj
  $ ajc CL.java; ajava CL
  CL$C@1172e08
  ------------------------------------------------------------
  before: initialization(CL.C())
  before: execution(CL.C())
  before: initialization(CL.1())
  before: execution(CL.1())
  before: call(String java.lang.Object.toString())
  CL$1@19f953d

and doesn't get the advice on the second instance.

Jeff







Back to the top