Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Using AspectJ to error when an implementing class does not declare a constructor

To check if any constructor defined by a class implementing
{type=Module} takes a ModuleContext, you can use the locution

   execution({type}.new(..)) && !execution(new(ModuleContext))

This forces the ModuleContext to be the first and only parameter.
You can also use

  ... && !execution(new(ModuleContext, ..))

to permit other parameters.

This picks up the case where no constructor is declare because
ajc (like all good Java compilers) generates a default no-argument
constructor if none are defined.

The code below shows that this works.  But it requires something
I didn't expect: for {type}, I expected to use "Module+", but
instead I had to use "(!Module && Module+)" (all subtypes of
module, but not module itself) in order to avoid getting an
extra error on each subtype of Module.  That makes it look like
there is an implicit separate constructor for the interface.
Looks like a bug to me.

Anyway, the code (with workaround) is below.  I hope this helps.

Wes

----- RequiredConstructors.java
public aspect RequiredConstructor {
    declare error : execution((!Module && Module+).new(..))
        && !execution(new(Module.ModuleContext,..))
        : "Module constructor should take a ModuleContext";
}

interface Module {
    public interface ModuleContext {
        String getSetting(String name);
    }
}

class A implements Module {} // error here

class B implements Module {
    B(Module.ModuleContext context, int i) {}
}

class C implements Module {
    C(Module.ModuleContext context) {}
}

class D implements Module {
    D(int i) {}  // error here
}


Matthew Denner wrote:

Hi,

I don't think this question has come up before but is it possible, with AspectJ, to declare an aspect that catches any classes that implement an interface but do not declare a particular constructor?

For instance, I have a Module interface something like this:

public interface Module {
    public interface ModuleContext {
        String getSetting(String name);
    }
}

Now, every class that implements the Module interface must (because of the way they are created through reflection) declare a constructor that takes a ModuleContext instance:

public class FooModule implements Module {
    public FooModule(ModuleContext context) {
        // get some settings from context
    }
}

But in Java you cannot enforce this at compile time, with interfaces (I know I could do an abstract class but this will open up another whole can of worms for me). For instance, the interface below is invalid as it doesn't have this constructor but the developer is not informed of this at compile time:

public class BadModule implements Module {

}

So, I was wondering if there is some way, using 'declare error' that I can spot this error at compile time?

Go slow, slightly new to AspectJ!

Matt
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users




Back to the top