Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] @DeclareParents

Uh... I don't know that I can... I'm getting totally inexplicable behavior... I copied the example I'd originally sent for RC1 (a couple of weeks back) and reworked it to the release semantics. But now, rather than seeing the setter act globally, I'm seeing that the setter does nothing... I've sent my work so far.

Mood.java
---------
package moody;

public enum Mood { HAPPY, JOLLY }

For classic, I have the following (there are a few slight differences from the documention -- I've added the method declarations to the interface (Moody) (including the setter), added a setter implementation, removed "feelingMoody" (which was not needed), and eliminated some whitespace to make it more compact):

ClassicMoodIndicator.aj
-----------------------
package moody;

public aspect ClassicMoodIndicator {
  public interface Moody {
     Mood getMood();
     void setMood(Mood mood);
  }

  private Mood Moody.mood = Mood.HAPPY;

  public Mood Moody.getMood() { return mood; }
  public void Moody.setMood(Mood mood) { this.mood = mood; }

  declare parents : moody.ClassicMoodImplementor implements Moody;
}

ClassicMoodImplementor.java
---------------------------
package moody;

public class ClassicMoodImplementor { }

For the annotation style I have (this matches the example, save the removal of some of the whitespace and "feelingMoody" and the addition of the setter):

AnnotationMoodIndicator.java
----------------------------
package moody;

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

@Aspect
public class AnnotationMoodIndicator {
  public interface Moody {
     Mood getMood();
     void setMood(Mood mood);
  }

  public static class MoodyImpl implements Moody {
     private Mood mood = Mood.HAPPY;

     public Mood getMood() { return mood; }
     public void setMood(Mood mood) { this.mood = mood; }
  }

@DeclareParents(value="moody.AnnotationMoodImplementor",defaultImpl=MoodyImpl.class)
  private Moody implementedInterface;
}

AnnotationMoodImplementor.java
------------------------------
package moody;

public class AnnotationMoodImplementor { }

My test class looks as follows:

MoodTester.java
---------------
package moody;

import junit.framework.TestCase;

public class MoodTester extends TestCase {
  public MoodTester(String name) { super(name); }
public static void main(String args[]) { junit.textui.TestRunner.run(MoodTester.class); }

  public void testClassic() {
     ClassicMoodImplementor cmi0 = new ClassicMoodImplementor();
     ClassicMoodImplementor cmi1 = new ClassicMoodImplementor();
assertEquals("cmi0 should be HAPPY", Mood.HAPPY, cmi0.getMood()); cmi1.setMood(Mood.JOLLY);
     assertEquals("cmi1 should be JOLLY", Mood.JOLLY, cmi1.getMood());
assertEquals("cmi0 should be *still* be HAPPY", Mood.HAPPY, cmi0.getMood());
  }
public void testAnnotation() {
     AnnotationMoodImplementor ami0 = new AnnotationMoodImplementor();
     AnnotationMoodImplementor ami1 = new AnnotationMoodImplementor();
assertEquals("ami0 should be HAPPY", Mood.HAPPY, ((AnnotationMoodIndicator.Moody) ami0).getMood()); ((AnnotationMoodIndicator.Moody) ami1).setMood(Mood.JOLLY); assertEquals("ami1 should be JOLLY", Mood.JOLLY, ((AnnotationMoodIndicator.Moody) ami1).getMood()); assertEquals("ami0 should be *still* be HAPPY", Mood.HAPPY, ((AnnotationMoodIndicator.Moody) ami0).getMood());
  }
}

The test run is as follows:
..F
Time: 0.021
There was 1 failure:
1) testAnnotation(moody.MoodTester)junit.framework.AssertionFailedError: ami1 should be JOLLY expected:<JOLLY> but was:<HAPPY>
       at moody.MoodTester.testAnnotation(MoodTester.java:27)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at moody.MoodTester.main(MoodTester.java:7)

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

I absolutely don't get why the setter had no effect... Note that it didn't fail on the third assert (that "ami0 should be *still* be HAPPY"), but on the second ("ami1 should be JOLLY")! I've confirmed that setMood is being invoked... So, rather than demonstrating "static-ness", I've only succeeded in showing that the setter does nothing... Help?!

Alexandre Vasseur wrote:

I am not sure I follow what you mean with static advice in this context.

Can you post the whole aspect or sample program with its
DeclareParents (similar to the @AspectJ one from http://eclipse.org/aspectj/doc/released/adk15notebook/ataspectj-itds.html)
and the actual "client code" (where there will be a cast as previously
discussed on this thread) such as in the doc:
Mood mood = ((Moody)this).getMood();
...


Thanks
Alex





On 12/23/05, Brian Ericson <bme@xxxxxxxx> wrote:
Thanks for the quick turnaround and updates to the documentation!  With
the updates, the example now compiles.

One last question/issue:  is the annotation-style advice supposed to be
static?

The two examples are not equivalent (in a subtle way that wouldn't be
apparent given the example, since the example has no setter)...

If I implement MoodIndicator using the "classic" style and create two
instances, each instance will have it's own mood (since the example has
no setter, both instances' values would be Mood.HAPPY).  In the
annotation style, the mood is static (shared).  This becomes evident if
I add a setter to both styles and change the value of one of the
instances, as the following pseudo code illustrates:
  MoodyGuy m0 = new MoodyGuy();
  m0.setMood(Mood.HAPPY); //the default...
  MoodyGuy m1 = new MoodyGuy();
  m1.setMood(Mood.JOLLY);

  if (m0.getMood() == m1.getMood()) System.out.println("Advice is static");
  else System.out.println("Advice is not static");

For classic, this would result in "Advice is not static", but for the
annotation style, this would produce "Advice is static" because setting
the mood on m1 affects m0.  Can the annotation-style be made non-static?

Adrian Colyer wrote:

I've now fixed the docs in CVS and in the online version.

On 22/12/05, Alexandre Vasseur <avasseur@xxxxxxxxx> wrote:


Hi Brian

I have spotted a little typo in the doc indeed.

First the syntax is
@DeclareParents(value=".....", defaultImpl=Some.class)
that is reference the class object itself, not the fully qualified name there.

Also, the static inner class must be static and public so that the
implicit no-arg constructor is public.

Alex



On 12/22/05, Brian Ericson <bme@xxxxxxxx> wrote:


The syntax for @DeclareParents changed slightly in the AspectJ 5
release.  I can't get the example to compile...  The first two hurdles
are minor:
o 'defaultImpl="MoodyImpl"' should be 'defaultImpl=MoodyImpl.class'
o 'void feelingMoody(Moody m) {' should be 'public void
feelingMoody(Moody m) {'

However, having made the changes, the compilation fails because
'defaultImpl="MoodIndicator$MoodyImpl" has no public no-arg
constructor'.  I've tried a number of things, but can't get beyond this...

Ideas?
_______________________________________________
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



--
-- Adrian
adrian.colyer@xxxxxxxxx
_______________________________________________
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