[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] @DeclareParents static?

I'm trying to understand the Moody example. My problem is that, when using the annotation style, everyone's CONFUSED -- if I confuse one instance, they all become confused (the advice is static)...

The classic makes sense (I'm using RC1):

package moodytest;

public enum Mood { HAPPY, SAD, CONFUSED }

package moodytest;

public aspect ClassicMoodIndicator {
public interface Moody {}
private Mood Moody.mood = Mood.HAPPY;
public Mood Moody.getMood() { return mood; }
public void Moody.setMood(Mood mood) { this.mood = mood; }
declare parents : moodytest.ClassicMoodyImplementor implements Moody;

package moodytest;

public class ClassicMoodyImplementor { }

package moodytest;

import junit.framework.TestCase;

public class ClassicMoodTester extends TestCase {
ClassicMoodyImplementor cmi0 = null;
ClassicMoodyImplementor cmi1 = null;
public ClassicMoodTester(String name) { super(name); }

  protected void setUp() throws Exception {
     cmi0 = new ClassicMoodyImplementor();
     cmi1 = new ClassicMoodyImplementor();

public void testHappyDefault() {
assertEquals("cmi0 should be happy!", Mood.HAPPY, cmi0.getMood());
public void testOneConfused() {
assertEquals("cmi0 should now be confused", Mood.CONFUSED, cmi0.getMood());
assertEquals("cmi1 should still be happy", Mood.HAPPY, cmi1.getMood());

As expected, all ClassicMoodTester tests run successfully. Now, for the annotation style...

package moodytest;

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

public class AnnotationMoodIndicator {
public interface Moody {
Mood getMood();
void setMood(Mood mood);
public class MoodyImpl implements Moody {
Mood mood = Mood.HAPPY;
public Mood getMood() { return mood; }
public void setMood(Mood mood) { this.mood = mood; }
public static Moody introduced = new AnnotationMoodIndicator().new MoodyImpl();

package moodytest;

public class AnnotationMoodyImplementor { }

package moodytest;

import junit.framework.TestCase;

public class AnnotationMoodTester extends TestCase {
AnnotationMoodyImplementor ami0 = null;
AnnotationMoodyImplementor ami1 = null;
public AnnotationMoodTester(String name) { super(name); }

  protected void setUp() throws Exception {
     ami0 = new AnnotationMoodyImplementor();
     ami1 = new AnnotationMoodyImplementor();

public void testHappyDefault() {
assertEquals("ami0 should be happy!", Mood.HAPPY, ami0.getMood());
public void testOneConfused() {
assertEquals("ami0 should now be confused", Mood.CONFUSED, ami0.getMood());
assertEquals("ami1 should still be happy", Mood.HAPPY, ami1.getMood());

Now, running the AnnotationMoodTester tests results in the following:
Time: 0.021
There was 1 failure:
1) testOneConfused(moodytest.AnnotationMoodTester)junit.framework.AssertionFailedError: ami1 should still be happy expected:<HAPPY> but was:<CONFUSED>
at moodytest.AnnotationMoodTester.testOneConfused(AnnotationMoodTester.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

Tests run: 2,  Failures: 1,  Errors: 0

Am I missing something, or is it intended that the introduction be static -- that all instances will always be of the same mood? Can I make the introduction non-static?

P.S. AnnotationMoodTester will not compile using AJDT (I get an internal compiler error at the beginning of the class), but compiles fine by hand.

P.P.S. I cannot compile all of the above classes in one pass using ajc. I need to first compile all but the tests, then compile the tests or the tests will not compile. Is this expected?