Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Mixins with @DeclareParents (M5)

Thanks for the response!

Sorry -- the "long test { getId(); } was mis-translated as I simplified it for the purposes of the post and should have been "public long test() { return getId(); } -- I'd hoped to be able to call the methods provided by advice in the advised classes, but while this worked outside of Eclipse, Eclipse+AJDT does not appear to like it (I'll try your suggestion to make ADJT the editor for all Java files). I've since removed that test, as I'm still trying to get basic annotation-style declare parents working.

Where I'm stuck now is the java.lang.VerifierError. To be clear, I'm trying three scenarios. The first, using the "Adrian-style" (in his blog linked to previously) does not work:
PersistentEntity.java
---------------------
package test;

public @interface PersistentEntity { }

PersistentEntityAspect.java
---------------------------
package test;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

@Aspect
public class PersistentEntityAspect {
  public interface Persistent {
     long getId();
     void setId(long id);
  }
public class PersistentImpl implements Persistent {
     long id = 0;
public long getId() { return id; }
     public void setId(long id) { this.id = id; }
  }
@DeclareParents("@test.PersistentEntity test.*") public static Persistent introduced = new PersistentEntityAspect().new PersistentImpl();
}

Test.java
---------
package test;

@PersistentEntity
public class Test { }

The second, using the "old-style" approach works:
PersistentEntity2.java
----------------------
package test;

public @interface PersistentEntity2 { }

PersistentEntityAspect2.aj
--------------------------
package test;

public aspect PersistentEntityAspect2 {
  public interface Persistent {
     long getId();
     void setId(long id);
  }
declare parents : @PersistentEntity2 * implements Persistent; long Persistent.id = 0; public long Persistent.getId() { return id; }
  public void Persistent.setId(long id) { this.id = id; }
}

Test2.java
----------
package test;

@PersistentEntity2
public class Test2 { }

The third, using the "moody-style" also does not work:
PersistentEntity3.java
----------------------
package test;

public @interface PersistentEntity3 { }

Persistent.java
---------------
package test;

public interface Persistent {
  long getId();
  void setId(long id);
}

PersistentImpl.java
-------------------
package test;

public class PersistentImpl implements Persistent {
  long id = 0;
public long getId() { return id; }
  public void setId(long id) { this.id = id; }
}

PersistentEntityAspect3.java
----------------------------
package test;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

@Aspect
public class PersistentEntityAspect3 {
  @DeclareParents("@test.PersistentEntity3 test.*")
  public static Persistent introduced = new PersistentImpl();
}

Test3.java
----------
package test;

@PersistentEntity3
public class Test3 { }

All three compile, and Test, Test2, and Test3 each have the AspectJ markers indicating advice, but the following test:
TestTests.java
--------------
package test;

public class TestTests {
  public static void main(String[] args) {
     try {
        final Test test = new Test();
System.out.println("test"+((test instanceof PersistentEntityAspect.Persistent) ? " " : "not ")+"advised");
     }
     catch (Throwable t) {
        System.out.println("test threw an exception!");
        t.printStackTrace();
     }
try {
        final Test2 test2 = new Test2();
System.out.println("test2"+((test2 instanceof PersistentEntityAspect2.Persistent) ? " " : "not ")+"advised");
     }
     catch (Throwable t) {
        System.out.println("test2 threw an exception!");
        t.printStackTrace();
     }
try {
        final Test3 test3 = new Test3();
System.out.println("test3"+((test3 instanceof Persistent) ? " " : "not ")+"advised");
     }
     catch (Throwable t) {
        System.out.println("test3 threw an exception!");
        t.printStackTrace();
     }
  }
}

gives the following result:
test threw an exception!
java.lang.VerifyError: (class: test/Test, method: setId signature: (J)V) Register pair 0/1 contains wrong type
       at test.TestTests.main(TestTests.java:6)
test2 advised
test3 threw an exception!
java.lang.VerifyError: (class: test/Test3, method: setId signature: (J)V) Register pair 0/1 contains wrong type
       at test.TestTests.main(TestTests.java:24)

I'm not sure what I'm doing wrong here...

Alexandru Popescu wrote:

I am not sure about this, but the PersistentImpl shouldn't be declared as static?


About Eclipse/AJDT: if you want to use directly the ITDs, I think you should set the AJDT editor as the default for all .java files.

However, I don't understand how this would look like:

[code]
For example, Test.java could not look as follows:
>> public Test {
>>   long test { return getId(); }
>> }
[/code]

Haven't you missed something? (some paranthesis, I guess).

./alex
--
.w( the_mindstorm )p.

#: Brian Ericson changed the world a bit at a time by saying on 11/23/2005 7:30 AM :#

Some progress... Moving everything to a "test" package and changing the declaration to:
@DeclareParents("@test.PersistentEntity test.*")
is enough to get AspectJ markers in Eclipse. However, an attempt to construct an instance of Test fails with the following exception: java.lang.VerifyError: (class: test/Test, method: setId signature: (J)V) Register pair 0/1 contains wrong type

I also reworked the "moody" example (in the documentation and sited in a thread below) using a Persistent interface and PersistentImpl implementation outside of the aspect, allowing me to do the following:
package test;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

@Aspect
public class PersistentEntityAspect {
   @DeclareParents("@test.PersistentEntity test.*")
   public static Persistent introduced = new PersistentImpl();
}

This fails with the same exception above. What am I doing wrong? This works for Adrian... (see http://www-128.ibm.com/developerworks/java/library/j-aopwork8/ ).

Brian Ericson wrote:

I'm trying to implement mixins using the @Aspect/@DeclareParents annotations. To begin with, the following works:
PersistentEntity.java:
public @interface PersistentEntity { }

PersistentEntityAspect.aj:
public aspect PersistentEntityAspect {
  public interface Persistent {
     long getId();
     void setId(long id);
  }
declare parents : @PersistentEntity * implements Persistent; long Persistent.id = 0; public long Persistent.getId() { return id; }
  public void Persistent.setId(long id) { this.id = id; }
}

Test.java:
@PersistentEntity
public class Test { }

Using Jython, I can see that Test implements PersistentEntityAspect.Persistent and can call both getId() and setId().

The following does not work (replacing PersistentEntityAspect.aj with PersistentEntityAspect.java):
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

@Aspect
public class PersistentEntityAspect {
  public interface Persistent {
     long getId();
     void setId(long id);
  }
public class PersistentImpl implements Persistent {
     long id;
         public long getId() { return id; }
     public void setId(long id) { this.id = id; }
  }
@DeclareParents("@PersistentEntity *") public static Persistent introduced = new PersistentEntityAspect().new PersistentImpl();
}

Test is not advised and does not implement any interface. (I did use the recent thread http://dev.eclipse.org/mhonarc/lists/aspectj-users/msg05032.html as reference, but this neither compiled (... introduced = new MoodyImpl();) nor did I get the advice bit working out. I must be doing something simple wrong (maybe I need to post-compile the result to weave it or use load-time weaving? I'm not sure how to do either (more research!))...

Other questions... Eclipse/AJDT does not allow me to use methods introduced by advice. For example, Test.java could not look as follows:
public Test {
  long test { return getId(); }
}

This actually compiles and runs correctly using ajc, but won't get compile in the IDE (The method getId() is undefined...).

Also, how're people using AspectJ with Maven 2? Confessing to be a newbie to both AspectJ and Maven, I'm currently "tricking" it by using ajc as my java compiler.
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top