Bug 257754 - @DeclareParents doesn't consider default contructor
Summary: @DeclareParents doesn't consider default contructor
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.6.3   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-12-05 13:52 EST by Ramnivas Laddad CLA
Modified: 2008-12-06 00:19 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ramnivas Laddad CLA 2008-12-05 13:52:57 EST
The following code gives an error due to the ignoring of the default constructor added by the compiler.

package example;

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

public class Main {
    public static void main(String[] args) {
        Bar bar = new Bar();
        ((Foo)bar).doFoo();
    }
}

interface Foo {
    public void doFoo();
}

class DefaultFoo implements Foo {
//    Uncommenting the following fixes the error    
//    public DefaultFoo() {
//    }
    public void doFoo() {
        System.out.println("In doFoo " + this.getClass());
        
    }
}

class Bar {
    public void doBar() {
        System.out.println("Bar");
    }
}

@Aspect
class Introduce {
    @DeclareParents(value="example.Bar", defaultImpl=DefaultFoo.class)
    private Foo mixin;
}

--
>ajc -version
AspectJ Compiler 1.6.3 (DEVELOPMENT - Built: Friday Nov 14, 2008 at 12:18:59 GMT) - Eclipse Compiler 0.785_R33x, 3.3
> ajc -source 6 example\*.java
> ..\DeclareParents\src\example\Main.java:34 [error] @DeclareParents: defaultImpl="example.DefaultFoo" has no public no-arg constructor
class Introduce {
      ^^^^^^^^

1 error
Comment 1 Andrew Clement CLA 2008-12-05 14:11:49 EST
a constructor is added by the compiler, but because the type DefaultFoo is not public, the generated constructor is not public (it is the same default package visibility). 
Comment 2 Andrew Clement CLA 2008-12-05 14:12:59 EST
so i guess the questions is whether that constructor is sufficient for AspectJ to implement delegation correctly.
Comment 3 Ramnivas Laddad CLA 2008-12-05 16:22:28 EST
Ah, I see... 

I think the current behavior is fine given that if the value attribute were to select a wider set of types, a public constructor will be needed. Hmmm... in that case, the type must be public as well even if the constructor is public (so that it can be accessed from each selected type). So may be the rule should be that the type must be public and the no-arg constructor must be public as well. Perhaps the error message could be updated. It could specifically point to one of the two problems or can be more general:
@DeclareParents: defaultImpl="example.DefaultFoo" is not a public type and/or has no public no-arg constructor

Given that this kind of situation will happen rarely, unless it is easy to fix, please treat it as a low priority bug (I got into this only because I was trying a toy example).
Comment 4 Andrew Clement CLA 2008-12-05 19:38:09 EST
I think it could be considered OK if the constructor visibility at least matches the type visibility.  If doing everything 'in package', then its ok if the ctor is just package visible (I've just tested that and it works ok).  I'll fix it to allow this case and improve the message.
Comment 5 Andrew Clement CLA 2008-12-06 00:19:04 EST
ok, fixed.  We tolerate a variance in ctor visibilities.  if the type itself can't be seen then that will result in a different error anyway.  When it is the visibility of the ctor (rather than it being missing), the compiler will produce a better error message.