There was a recent post to the aspectj-users group from "Frustrated Newbie" who was trying to write a declare error that would enforce the requirement that all classes implementing one interface, let's call it Foo, also implement a second interface Bar. He tried something like the following:
1
2

declare error: within(*..Foo+) && !within(*..*Bar+):
This doesn't work, mostly because interfaces don't have much real code associated with them, so there aren't enough join points to match. As an experiment (which he tried...), if you drop the second expression, leaving just within(*..Foo+) you get an error just on the Foo interface, not on any implementing classes or extending interfaces. Through trial and error, I figured out that if you put these interfaces in dedicated packages, say ..foo and ..bar, respectively, the following does work:
1
2

declare error: within(*..foo.*+) && !within(*..foo.*) && !within(*..bar.*+):
The second expression !within(*..foo.*) prevents errors on the interfaces in package foo itself. This isn't especially obvious and you may find it inconvenient to package your interfaces like this, but it does work. Actually, there's a good case to be made for putting interfaces in separate packages like this, based on the Stable Abstractions Principle (PDF, see also here).

5 Responses to “AspectJ: Testing that Classes Implement All Required Interfaces”

  1. deanwampler Says:
    Hi, Dean. I am glad that it somehow worked in the end. However, I was wondering why people repeatedly misuse AOP for such purposes. IMHO the one and only correct way to enforce that an interface Foo also implements a second interface Bar is to make it a subtype of Bar. It's no surprise that people struggle applying AOP for purposes it was not developed for, in particular if they already don't get OOP right. Eric
  2. deanwampler Says:
    I fully agree with Eric. These types of usages of AOP will give it a bad name. Obviously the *declare error* that Dean has come up with does not look pretty on the face of it. Particularly in the days of DSLs, these usages will lead people to believe that AOP is a technology to fit a square peg in a round hole. Cheers. - Debasish
  3. deanwampler Says:
    I agree with both of you that it's ugly. It would be better for languages to offer something more native or for AspectJ to provide the expressiveness necessary for a more elegant solution. I don't necessarily agree that this is a misuse of AOP. I thought about this issue when I developed Contract4J, my DbC tool for Java. On the one hand, the contract of a component IS part of its concern, not a cross-cutting concern. On the other hand, how you USE that contract, e.g., for "proving correctness" through DbC is not part of the primary concern of the application. In that sense, DbC is a cross-cutting concern. Maybe this is a silly academic argument ;) Whether or not that's true, I don't have a problem with using a tool to solve a problem I can't solve by other means, even if that usage seems to be outside the tool's main application area. Eric, concerning the idea that Foo should extend Bar, I think that solution won't work in all cases. You can come up with different "mixin" interfaces that are unrelated and hence should not have an artificial inheritance relationship. However, "Frustrated Newbie" could probably declare an implementation-specific interface that extends both Foo and Bar and then requires all his classes to implement that interface. Thanks for you comments. Dean
  4. Baitigozoob Says:

    bridget marquardt ixgtnqf girls next door kendra qpqmpni kendra wilkinson naked fhodbas kendra wilkinson pics

    http://www.justin.tv/lisaa23/profile bridget marquardt http://www.justin.tv/mastarew/profile girls next door kendra http://www.justin.tv/kamara23/profile kendra wilkinson naked http://openlibrary.org/user/tilaa kendra wilkinson pics

  5. Liza Says:

    My fellow on Facebook shared this link with me and I’m not dissapointed at all that I came to your blog.

Sorry, comments are closed for this article.