Bug 280658 - @DeclareParents doesn't work very well !
Summary: @DeclareParents doesn't work very well !
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows NT
: P5 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-06-17 14:11 EDT by Andrew Clement CLA
Modified: 2010-01-12 20:07 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Clement CLA 2009-06-17 14:11:58 EDT
Reported by Tom Dunstan:

Hi all. We have some existing aspects that use @DeclareParents to add an interface with a default implementation
to some classes. We have been using Spring to create proxies based on our aspects at runtime, however we have
hit some issues with code signing  (it's a Webstart app) so I'm trying to get compile-time weaving going instead.
 
I seem to be hitting some issues though. I'll leave the Eclipse AJDT issues aside for now, I'll just concentrate on
issues running the AspectJ compiler on its own.
 
Before I start - one odd thing I noticed is that when running both the 1.6.4 compiler and the the latest development
one (from aspectj-DEVELOPMENT-20090612201410.jar), the compiler reports as being version 1.6.3, I don't know if that's
a source of problems or not:
 
>\development\aspectj1.6.4\bin\ajc -version
AspectJ Compiler 1.6.3 (1.6.3 - Built: Tuesday Dec 23, 2008 at 17:12:30 GMT) - Eclipse Compiler 0.785_R33x, 3.3
 
I have a couple of test aspects and a target file that should get woven accordingly (imports omitted for brevity):
 
package aspects;
@Aspect
public class ParentsAspect {
 
    @DeclareParents(value = "test.Foo", defaultImpl = DebugDefault.class)
    public Runnable runnable;
 
    public static class DebugDefault implements Runnable {
        public void run() {
            System.out.println("hi there from ParentsAspect");
        }
    }
}
 
@Aspect
public class MixinAspect {
    @DeclareMixin(value = "test.Foo")
    public static Runnable foo(Object target) {
        return new DebugDefault();
    }
 
    public static class DebugDefault implements Runnable {
        public void run() {
            System.out.println("Hi there from MixinAspect");
        }
    }
}
 
package test;
public class Foo {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(new Foo().getClass().getInterfaces()));
        ((Runnable) new Foo()).run();
    }
}
 
When I try to apply the parents aspect, I get the following (no warnings about versions from the dev build btw, but otherwise the same results):
 
>\development\aspectj1.6.4\bin\ajc -outjar aspects.jar src\java\aspects\ParentsAspect.java -1.5
[warning] bad version number found in c:\Development\aspectj1.6.4\lib\aspectjrt.jar expected 1.6.3 found 1.6.4
 

1 warning
 
>\development\aspectj1.6.4\bin\ajc -aspectpath aspects.jar -outjar app.jar src\java\test\Foo.java -showWeaveInfo -1.5
[warning] bad version number found in c:\Development\aspectj1.6.4\lib\aspectjrt.jar expected 1.6.3 found 1.6.4
 
C:\Development\eclipse-workspace\e3.4.2\AspectJTestAspect\src\java\test\Foo.java:12 [error] The type Foo must implement
the inherited abstract method Runnable.run()
public class Foo {
             ^^
 
1 error, 1 warning
 
So it has picked up that Foo should implement Runnable, but hasn't supplied the implementation.
 
If I try the mixin aspect, I get no errors, no weave info and Foo has not had the aspect applied.
 
Interestingly, I get the first error for BOTH aspects in Eclipse using the AJDT, but only when Foo is in a different project to the aspects - when in the same project it works fine.
 
So, am I doing something fundamentally wrong? Am I using a dodgy compiler? (I downloaded the dev and 1.6.4 builds from eclipse.org yesterday) Something else strange going on?
 
Any help much appreciated.
 
Cheers
 
Tom
---
Both my ParentsAspect and MixinAspect are applied successfully to test.Foo when it's in the same project, but if I try to get them to apply to Foo in another project that has the original one in its aspectpath, I get the "The type Foo must implement the inherited abstract method Runnable.run()" error for either one. I noted that there was a bug at one point around having the same class/package in multiple projects, but this persists even when I change the package / classname of Foo. The error is in both the editor and the problems list.
Comment 1 Andrew Clement CLA 2009-06-17 16:13:42 EDT
really broken here.  The big problems are:

1) The type is resolved too early so the xlint comes out about being unable to find test.Foo.

2) The new parent is added far too early causing the problem about run() not being implemented because JDT is checking the type.  The interface should not be added until much later (during weaving - and that is why the cast is required)

declare mixin is the way to go
Comment 2 Andrew Clement CLA 2010-01-12 20:07:34 EST
DeclareMixin supercedes DeclareParents