Skip to main content

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

Embedded.

Adrian Colyer wrote:

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.

It *should* be exactly the same compiler used on the command-line and
from within AJDT (do you have source level 1.5 set on your project?),
assuming you're using AJDT RC1. Any descrepancy will certainly have to
be investigated...
I'm using the latest AJDT. I've looked further into this since receiving your email... The issue isn't so much that AJDT can't compile the files in the project, it's that it easily gets into a "funk" and won't compile from then on without running Project -> Clean.

For example, I can open the files I've listed, see them error-free in the IDE (sorry -- that's if I add the casts as recommended), and then add and delete a space in one of the files (I'm doing this in AnnotationMoodyImplementer.java) and save the file and get an internal error. From then on, the project won't compile until I clean it.

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?

Using the @AspectJ style, we restrict the support to the subset of
things that javac could compile. This is why we only support the
declare parents ... implements style and not general ITDs etc. So when
using @AspectJ, you can't make a compile-time assumption that a target
of the declare parents implements the interface (from the perspective
of javac, it doesn't). In AnnotationMoodTester therefore, you need to
cast ami0 and ami1 to (Moody) before you can call Moody methods. The
cast should succeed at runtime of course, because of the
@DeclareParents statement.
Thanks -- the cast works. I could've sworn this wouldn't work because I felt sure the compiler would complain that the cast was "impossible", but it's possible to compile all the files in one pass with the casts.

Interestingly, if I'm willing to compile the AnnotionMoodTester.java file in a second pass, I don't need to do the cast (that is, if I compile Mood.java, AnnotationMoodIndicator.java, and AnnotationMoodyImplementor.java in one pass using ajc, and then AnnotationMoodTester in a second pass, the compile will succeed even if I don't do the explicit casts)...

Is there a particular reason the two-pass compile succeeds w/o the cast, but the one-pass requires the cast? I'd prefer not to cast, but that's not a big deal.

On 16/12/05, Alexandre Vasseur <avasseur@xxxxxxxxx> wrote:
I'll look at that - possibly a bug.
Alex

On 12/16/05, Brian Ericson <bme@xxxxxxxx> wrote:
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):

Mood.java
---------
package moodytest;

public enum Mood { HAPPY, SAD, CONFUSED }

ClassicMoodIndicator.aj
-----------------------
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;
}

ClassicMoodImplementor.java
---------------------------
package moodytest;

public class ClassicMoodyImplementor { }

ClassicMoodTester.java
----------------------
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() {
     cmi0.setMood(Mood.CONFUSED);
     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...

AnnotationMoodIndicator.java
----------------------------
package moodytest;

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 class MoodyImpl implements Moody {
     Mood mood = Mood.HAPPY;

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

  @DeclareParents("moodytest.AnnotationMoodyImplementor")
  public static Moody introduced = new AnnotationMoodIndicator().new
MoodyImpl();
}

AnnotationMoodyImplementor.java
-------------------------------
package moodytest;

public class AnnotationMoodyImplementor { }

AnnotationMoodTester.java
-------------------------
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() {
     ami0.setMood(Mood.CONFUSED);
     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:
..F
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)

FAILURES!!!
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?
_______________________________________________
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


Back to the top