Tech Talk with Gregor Kiczales on Aspect Oriented Programming

Discussions

News: Tech Talk with Gregor Kiczales on Aspect Oriented Programming

  1. In this interview Gregor, leader of the PARC project that developed AOP and AspectJ, looks at the history of AOP and the current challenges it faces moving forward. He discusses the meaning of crosscutting structure, the standardization of AOP, how AOP and OOP fit together, and addresses syntactical issues surrounding AOP. He looks at the current state of AspectJ and predicts the impact AOP will have on software development.

    See the Gregor Kiczales' Interview on Aspect Oriented Programming

    What are your thoughts?

    Threaded Messages (71)

  2. Interesting, but I'm missing some Q&A on the relationship between AOP and meteadata (JSR175). I have myself found that using runtime attributes is a great way to define pointcuts, but IIRC Gregor has a different view on this. It'd be great if we could pin down the pros and cons of this approach.
  3. AOP and meteadata (JSR175)[ Go to top ]

    Interesting, but I'm missing some Q&A on the relationship between AOP and meteadata (JSR175). I have myself found that using runtime attributes is a great way to define pointcuts, but IIRC Gregor has a different view on this. It'd be great if we could pin down the pros and cons of this approach.


    The interview was already pretty long! :) But this would have been good to include.

    Here's my opinion... Its clear that using attributes with AOP is very useful. As soon as JSR175 is done I suspect AspectJ at least will be extended to allow pointcuts to match based on attributes.

    As time goes by, we'll learn when its best to use pointcuts based on attributes and when its best to use other kinds of pointcuts.

    In using pointcuts based on attributes, I think there are some subtle style issues, that we're going to have to work out. Some of these have been raised in thread http://www.theserverside.com/discussion/thread.jsp?thread_id=20514.

    It is clear that certain styles of using attributes are "just macros" or "just declarative programming". Of course that isn't a bad thing per se, but it may fail to give all the modularity benefits we want. It also may make it difficult to use the most powerful feature of AOP -- pointcut composition.

    I *think* that when using attributes we should be careful to give them names that describes a property of the 'POJD' (plain old Java declarations) they describe, and then have an advice-like construct say what aspect should apply to POJDs with that attribute. This is in contrast to much existing practice where the attribute directly names the aspect that should apply.

    To be concrete, let me use the well-worn figure example. I believe we should write code like this (assume of course the method is in a class and the advice is in an aspect):

      @ChangesDisplayState
      void setX(int x) { this.x = x; }

      after(): call(@ChangesDisplayState * *(..)) { Display.update(); }


    Rather than code like this:

      @UpdateDisplay
      void setX(int x) { this.x = x; }

      after(): call(@UpdateDisplay * *(..)) { Display.update(); }

    The reason I believe this is that it better modularizes the crosscutting concern.

    The crosscutting concern in this code is "methods that change display state should update the display". In the first code that is modularized in the advice. A second concern, "which methods change display state" is spread out.

    In the second code the two concerns are mixed together and both are spread out.

    I believe the practical impact of following this style is that you will end up with attribute names that are more reusable -- you will be more likely to be able to use an existing attribute in a new pointcut in useful ways.


    P.S. Note that if you write without attributes, something like:

    pointcut changesDisplayState(): call(void Point.setX(int)) || ...;

    after(): changesDisplayState() { Display.update(); }

    then both concerns are well localized in the code! Which just goes back to that we have some learning to do in terms of guidelines for when to use attributes and when not to. I'm writing something about that now, but its not ready to send out.
  4. AOP and meteadata (JSR175)[ Go to top ]

    I *think* that when using attributes we should be careful to give them names

    > that describes a property of the 'POJD' (plain old Java declarations) they
    > describe, and then have an advice-like construct say what aspect should apply
    > to POJDs with that attribute. This is in contrast to much existing practice
    > where the attribute directly names the aspect that should apply.

    I agree. For example, in our CMS code we have an attribute "readonly" that is applied to methods that doesn't change the state of the object. This can be picked up both by persistence advice (save on call to !readonly) and synchronization advice (read-lock object on readonly, write-lock on !readonly). The attribute describes something about the behaviour of the method body instead of doing "declarative programming" (e.g. "modifiesstate" and "readlock" respectively).

    > To be concrete, let me use the well-worn figure example. I believe we should write code like this (assume of course the method is in a class and the advice is in an aspect):
    >
    > @ChangesDisplayState
    > void setX(int x) { this.x = x; }
    >
    > after(): call(@ChangesDisplayState * *(..)) { Display.update(); }
    >
    > Rather than code like this:
    >
    > @UpdateDisplay
    > void setX(int x) { this.x = x; }
    >
    > after(): call(@UpdateDisplay * *(..)) { Display.update(); }

    Or even:
        @ReadOnly
       int getX() { return x; }
       void setX(int x) { this.x = x; }
     
       after(): call(!@ReadOnly * *(..)) { Display.update(); }
    (I don't know about AspectJ syntax, but I assume that the ! operator works as intended above)

    Anyway, the above is (roughly) how we do it in our code/framework.

    > The reason I believe this is that it better modularizes the crosscutting
    > concern.

    Absolutely. It minimizes coupling. Of course, you still need to choose attribute names that describe the methods in a way that is meaningful for the advice that should be applied. So, trying to completely ignore what advice are possible is probably not going to feasible. However, I do believe that experience will provide us with good examples of "standard" attributes (e.g. "readonly") that can be easily reused for many kinds of advice.

    > I believe the practical impact of following this style is that you will end up
    > with attribute names that are more reusable -- you will be more likely to be
    > able to use an existing attribute in a new pointcut in useful ways.

    Agree again.

    > P.S. Note that if you write without attributes, something like:
    >
    > pointcut changesDisplayState(): call(void Point.setX(int)) || ...;

    Why not:
    pointcut changesDisplayState(): !@ReadOnly;

    after(): changesDisplayState() { Display.update(); }
    --
    Seems like an even better approach. The main problem with the method enumeration comes with refactoring (if you use * that is, otherwise it's "just a tool issue").

    Anyway, good to know where you stand on this issue.

    Personally, if I have to declare somehow (for example) that a method is transactional I:
     1) don't want it in XML 2) don't want it in a method regexp pointcut for the tx advice 3) don't want it in the code (i.e. no AOP at all). I would in this case very much prefer to simply mark the method with "transaction=required", because it is then easy to see how the method will behave, without having to know exactly how that contract is enforced. That is a good use of attributes in AOP I think. And for each good use of attributes for pointcuts there's probably a ton of bad ones :-)

    /Rickard
  5. AOP and meteadata (JSR175)[ Go to top ]

    I think I understand what you guys are talking about, but at the same time my vocabularly isn't up to all the details y'all are discussing, so I may be mistaken :-) Anyway, let me paraphrase in my own language to see if I have it right (and if so, let me say I like the idea!).

    What I'm hearing described are two distinct uses of meta data. Specifically:

       1) Meta data requesting someone add new semantics to the existing code.
       2) Meta data declaring the existing semantics of the code

    In case "1", you could be requesting "transaction=required". The existing Java code isn't transactional, but you'd like someone to make it that way.

    In case "2", you could be saying "read_only", meaning that the current code doesn't mutate the state of the object graph.

    Case 1 (request) is what I consider declarative programming (or macros) - you're explicitly saying please make me transactional, or what have you.

    Case 2 (my semantics) is extending Java's qualifiers to convey more information on what the existing code is doing.

    Either one could be used as hooks that are used by an AOP system, but the type of hooks exist at different levels.

    Both cases, in my mind, are somewhat similar to taking the concept of Java interfaces and pulling them down to the individual method level. The person developing the code is directly adding them in. The difference between the two is that in case 1 (request), you're almost creating an abstract class that needs to be filled in by someone else (in this case, an aspect w/ advice "fills it in"). In case 2 (my semantics), you're only describing what the code does, and it's concrete - it can work on its own. But a developer can hook into that additional semantic information and create more accurate pointcuts to add in something like "transactional".

    From a pragmatic perspective, case 1 (request) is locking you in to a behavior. The class writer is saying, for example, "this class/method needs to be transactional", but it's not now, so somehow it has to be made so. It's morally equivalent to declaring transaction information for EJBs - the writer of the class has to know about transactions. And at the same time, _the class won't work if someone doesn't fill in behavior for them_.

    Case 2 (my semantics) is adding in more high level summary semantic information about methods/classes. It indicates what a class/method does in greater detail, and this greater detail can make it easier to write a "transaction" aspect, or "event notifier" aspect. But while it makes writing these aspects easier, the original class writer isn't aware of these things, and the class is fully operational without them. You can re-use this class in many applications, each of which uses different aspects to add different additional behavior. Ultimately, these semantic-tags can make it possible to write much more precise pointcuts which aren't just matching on Java language constructs, but higher level design notes as well.

    Is this more or less right, or have I badly misread everything again?

        -Mike
  6. AOP and meteadata (JSR175)[ Go to top ]

    The interview is a good read. And it is good to know that you (Gregor Kiczales aka "The father of AOP") supports runtime attributes in AOP. It seems that this response needs to be added in that interview (if possible).

    Runtime attribute are very very useful, MS reconized this early on, that's why they building a lot of things around it. After all it is, AOP = Annotated/ion Oriented Programming :-)
  7. Thanks to the good question from Rickard, and Gregors response.

    I have added that content back into the interview itself.

    Let's keep the good discussion going :)

    Dion
  8. Annotated concerns[ Go to top ]

    I notice that both of you use the same example to illustrate pointcuts with annotations: readonly (or changestate).

    Intuitively, I feel that an AOP framework should support all types of pointcuts (both external and internal) but except for the above example, I can't find another convincing use case.

    Like Gregor, I have the feeling that annotated pointcuts should tell something generic about the method they are annotating, and not describe what it does. They should be conceptual. ChangeState is a good example, and I was thinking that something like Idempotent is another one: this indicates that this method can be called several times (stateless). An application could typically make use of that information to implement failover and retry a call that has just failed, knowing that it is not going to cause an inconsistency in the state of the application.

    How do you identify what a good "Annotated concern" is? Maybe a good hint is: it can be represented by very different implementations. An "annotated concern" like "ChangeState" is very broad indeed. A method can be one line long or a hundred lines long and still fall in this category. It can be called setPoint() or foo() and still deserve the annotation ChangeState.

    With this definition, UpdateDisplay immediately comes out as suspicious: it is way too specific and tied to the implementation. As would something like UpdateDatabase (how about the more generic "SaveState" instead?).

    But I am still annoyed at the poverty of examples to support this assertion. It's a bit like trying to advocate AOP by implementing logging in an aspect... if you repeat the same example over and over, you lose your ability to convince.

    I am also worried by the fragility of the regexp approach. If ever a developer renames a method or moves it to a different class, the pointcut might no longer find it. Worse: you can imagine a situation where you have two different developers: one who wrote the business code (let's call him B) and one wrote the aspect (A). And in the purest illustration of separation of concerns, B has no idea what aspects have been written around his code, so he doesn't even have the possibility to modify the aspect in parallel (which should raise concerns of coupling anyway).

    I think this is a real concern (no pun intended) in taking AOP to a big scale, especially since IDE's nowadays make it so easy to do major refactorings.
  9. Annotated concerns[ Go to top ]

    How do you identify what a good "Annotated concern" is? Maybe a good hint is: it can be represented by very different implementations. An "annotated concern" like "ChangeState" is very broad indeed. A method can be one line long or a hundred lines long and still fall in this category. It can be called setPoint() or foo() and still deserve the annotation ChangeState.

    >
    > With this definition, UpdateDisplay immediately comes out as suspicious: it is way too specific and tied to the implementation. As would something like UpdateDatabase (how about the more generic "SaveState" instead?).

    This is an interesting point, I think.
     
    > I am also worried by the fragility of the regexp approach. If ever a developer renames a method or moves it to a different class, the pointcut might no longer find it. Worse: you can imagine a situation where you have two different developers: one who wrote the business code (let's call him B) and one wrote the aspect (A). And in the purest illustration of separation of concerns, B has no idea what aspects have been written around his code, so he doesn't even have the possibility to modify the aspect in parallel (which should raise concerns of coupling anyway).
    >
    > I think this is a real concern (no pun intended) in taking AOP to a big scale, especially since IDE's nowadays make it so easy to do major refactorings.

    People in the AOP community have started working on this issue. Making pointcut specifications more precise, so that they are based more on the properties of the joinpoints rather than on their syntax would be the ultimate, but difficult, goal to follow. An approach that combines the regexp approach with a sound "intentional" annotation approach might be a first easier step. In addition, tool support should also help. I know people that have put on their agenda the goal to develop "aspect-aware" refactoring tools.
  10. Annotated concerns[ Go to top ]

    Shigeru Chiba (javassist's author) has an interesting paper related to annotating topic (presented on JBoss conf.): http://www.csg.is.titech.ac.jp/~chiba/javassist/jboss2.pdf

    Regards,
    Nikita Ivanov.
  11. Annotated concerns[ Go to top ]

    Shigeru Chiba (javassist's author) has an interesting paper

    > related to annotating topic (presented on JBoss conf.):
    > http://www.csg.is.titech.ac.jp/~chiba/javassist/jboss2.pdf

    Yep, I believe this is the correct approach.

    Regexp may have a place in scripting, but not in programming.

    /T
  12. Annotated concerns[ Go to top ]

    \Thomas Mattson\
    Yep, I believe this is the correct approach.

    Regexp may have a place in scripting, but not in programming.
    \Thomas Mattson\

    If you don't use some form of regexp, you face some problems:

      1) Too much metadata in a target primary class can lead to adding multiple concerns to that class.

      2) Avoiding the above by creating pointcuts off only "my semantics" type tags (my terminology, see previous post) require that all your target classes/members use these tags

      3) You can avoid (2) above by adding either "my semantics" or "request" type metadata in a seperate config/aspect, such as Rickard's et al's suggestion. But this, or directly embedding "request" type meta tags (again, my terminology), can be very tedious. Sometimes very explicit is a very-pain-in-the-ass.

      4) Going explicit via tags means you're ignoring the semantic content which is already available in the Java language at the class/method/member level. And sometimes this plain-old-Java semantic is precisely what you need to key off of.

    Look at Gregor's example:

      call(public * com.us.product..*.*(..))

    This selects all public methods in a given package (and all its classes and classes within sub-packages). And it is a very, very useful type of joinpoint for certain applications. The alternative without regexps would be to find all the classes in those packages and annotate them directly, or define external meta data against each and every one, or have a giant list of point cuts that hits each individual method. Any of those solutions is actually much more fragile than the regexp approach, because you're forcing the developers to manually add in the meta-data/pointcuts everytime a method or class is added to those packages.

    Very useful refinements to the regexp system, such as "target (Product+)", which selects all "Product" classes _and classes extending it_, again is letting you select classes based on how they fit into the Java type system, but now in a different way (via class hierarchies this time, instead of via package naming).

    What you need to keep in mind is that the AspectJ regexp system isn't a simple textual regexp like you'd see in a naive perl program. It's a regexp applied over the meta-data about your Java application and libraries structure, and as such allows you to define pointcuts in terms of your codes structure (not flat textual representation, but the real structure).

    You can, of course, get into trouble in using it, and it is not applicable to all situations. Sometimes explicit enumeration of various joinpoints (or building up pointcuts based on meta-data, or something like it) is the better way to go. But abandoning it would make using AOP in Java feel akin to trying to do OOP in C. Possible, but at the same time probably so painful that the result wasn't worth the effort.

        -Mike
  13. collected short replies[ Go to top ]

    (sorry for not responding sooner, I was offline all day yesterday to see Glen Vandenburg's AOP w/ AspectJ tutorial at NFJS)

    Cedric said:
    > Like Gregor, I have the feeling that annotated pointcuts should tell something generic about the method they are annotating...

    I'm actually saying something slightly different, which is just that the annotation should describe what the method does. In a later message Mike Spille calls this "Case 2 (my semantics)". I'm not saying anything about whether its high or low level, I imagine both could be useful. But by being about the method (or field, constructor...) they are more robust if you later change the aspects, add new ones etc.

    Cedric said:
    > I am also worried by the fragility of the regexp approach. If ever a developer renames a method or moves it to a different class, the pointcut might no longer find it.
    (and others said similar things)

    A first point to make about the regexp approach -- AspectJ supports only very limited regexp functionality, and for a reason. The thing is some 'regexps' are clearly ok, for example:

      call(public * com.us.product..*.*(..))

    is stable as all get out, it says the public methods of our product. And

      call(* FigureElement+.set*(..))

    is also fine. It picks out a well known naming convention, from a very small sub-part of the total class structure. It may be a little less stable than the one above, but its pretty stable.

    And the refactoring thing is going to be less of an issue, as refactoring support in the IDEs will automatically identify things that are renamed or otherwise moved into or out of the scope of a pointcut.

    So the regexp issue is not as simple as just saying regexps are bad. It really depends on what you write. That's why AspectJ's regexp support is so limited.

    I think the guidelines are going to end up feeling something like:

     - If you can write a stable pointcut without using annotations, do so.

     - If there are many points, try not to use annotations.

     - If the insight required to capture whether a property holds for a member can't be captured by a stable type/name/modifier pattern, then use an annotation.

    And as Adrian points out, once you have added annotations, the actual pointcut is going to feel property based. I.e., the following two poincuts feel property based:

      call(public * com.us.product..*.*(..))
      call(@ChangesDisplayState * *(..))

    Once we have a couple years of experience programming this way, this will be excellent input to language designers as to what kinds of properties would be good to support directly in the language. In other words, some of our attributed based pointcuts may be able to be written w/o attributes. That's the kind of thing the speculative version of the display updating example in my AOSD talk is about.
  14. AOP and metadata (JSR175)[ Go to top ]

    There are two sides to the AspectJ and metadata question, and so far the discussion has only touched on one of them. Let me try and explain where I see the fit...

    Firstly, it seems clear to me that once we have metadata support in the Java language, we will need a form of the AspectJ 'declare' statement that declares metadata to be associated with program elements. (This is the reverse situation to the discussion so far). Thus in one declare statement I could add, say, a 'secure' tag to a set of classes, methods or even fields. The reason I believe this is important is that we will see (are already seeing) middleware and other applications that take action based on metadata.

    Once we have the ability to add metadata tags to program elements, it is only natural to use them as an extension to the 'property-based' pointcut style. That is, I can write advice that applies to 'secure' entities. Like Ramnivas, Mira and Gregor (see their respective posts) I am much more comfortable with this use of metadata for property-based pointcut declarations than in metadata that explicitly says which advice must apply.

    This combination of declaring metadata attributes via a crosscutting declares statement, and then subsequently using them for property-based pointcuts (and hence advice) is a natural extension of a common aspectj idiom: today you frequently see the use of a declare parents to add a marker interface to set of classes, followed by advice targeted to instances of that marker. Metadata will make this idiom more powerful by giving us finer granularity of 'marking' (down to member level), and I know from my own experience that there have been occasions when I would have found this useful.

    Since we've accepted pointcuts based on metadata for the reasons stated above, that also means that pointcuts could be written based on metadata captured explicitly in the source code (as opposed to introduced via a declare statement). Indeed, there should be no way for the pointcut matching engine to tell the difference. Therefore this usage would be supported. The interesting question then becomes, when is it good style to do things that way? Personally, I always prefer a robust property-based or principle-based pointcut where one is available, but if you have a situation where there is no common theme to the points of interest, such that the pointcuts would need to very specific and hence more fragile in the face of program evolution, then the inline declaration of a property (metadata attribute) to be picked out by a pointcut can be a good solution. I expect that explicit metadata declaration in this manner will be limited to cases where there are a relatively small and specialized number of points of interest.
  15. Rickard, checkout http://www.freeroller.net/page/fx/20030725#pointcutting_strategies_in_aspectwerkz for pros/cons of defining pointcuts using attributes vs regexps in XML.

    Here's the entry(so freeroller doesn't get TSS'd:)

    "I was wondering how other AspectWerkz users pointcut aspects in their apps.
    Basically you have the aspectwerk javadoc tag approach versus the XML approach.
    I'm especially interested in what makes you choose which specific pointcut approach
    to weave your aspects into your applications.

    What I like about the XML approach is:
  16. You can use regular expressions to easily pointcut aspects very quickly over parts or even the whole app.

  17. A good example usage for this is a ProfilerAdvice, which times each method call to find bottlenecks in the runtime.
    This would be a nightmare to accomplish using aspectwerkz doclets in the sourcecoce.
  18. You have all your pointcuts defined in one centralized file. It also seems to support the "separation of concerns" better than doclets:
    Instead of defining in your source code which advices a method needs, you define in the XML file, which advices to apply
    to which methods/classes/package. This seems more modular to me.

  19. Serves the obliviousness concept in aspect developing, especially for system aspects: Aspect developers are oblivious
    to the applications, where the aspect gets deployed. On the other side, application developers are oblivious to the system aspects,
    which are deployed to their app at runtime. Using XML, application code and aspect code are decoupled to the max. This is also
    very dangerous I think.


  20. What I like about the doclet approach is:

  21. You have much better and finer control over your pointcuts. You can add an advice at a specific position in the advice chain.

  22. I also like that both application code and aspects reside in one single source file. Like this, I can immediately see at development
    time, which advices get executed in which order for a specific method. This is very powerful I think and a major drawback of using
    XML. Especially in conjunction with the use of regexp's, this clearness very soon fades away.

  23. Regarding refactoring, the doclet appraoch absolutely rules. You can repackage your app and rename methods and classes and you
    do not have to do one thing to adapt your pointcuts. But when using XML and regexp's you need to invest some time to change all your
    definitions after you have refactored your app.

  24. Kind of still serves the oblivousness concept described above, however application developers have better control about which
    aspects are pointcut (think persistency, transaction -> these are very application specific due to your project requirements, but are
    still system aspects by nature)


  25. So, with all this being written down I can say, that I currently prefer the doclet approach. Although I like the XML approach
    theoretically and conceptually better, in practical life it doesn't have much value for me. I still do some mix&match though.
    The most common examples for me to use the XML approach I currently see are profiling and logging. For almost everything else
    I do use attributes. By doing so, I somehow combine the advantages of both concepts. Of course I also combine their disadvantages.
    And on top of this, mixing both approaches sometimes reaally confuses the hell out of me about the order in which my pointcuts get
    weaved."
  • One more thing: when I say "metadata" it's important to distinguish between the actual associations between classes/methods/fields and these attributes and how these associations are done. Using tags in source code is *one* way to do this, but certainly not the only one. As but one example, in our own AOP/metadata framework we allow attributes to be defined in XML-files which are read at startup and added to the set of runtime attributes gathered through source code doclet tags. This way we can have one set of attributes which are always the same (=defined in code) and some of which are more deployment oriented (=defined in XML). It seems like most people think "doclet tags" when you talk about metadata, but that's (to me) just one input method among others.
  • Indeed, there are multiple ways--and not just tags--to express
    metadata to implement crosscutting concerns.

    In AspectJ, the way I deal with the situations that require
    use of metadata to capture join points is to use what I call
    the "participant pattern". This pattern gives many of the same
    benefits as the metadata tags approach, except the granularity
    and style of expressing the metadata is changed. The pattern is
    fairly straightforward:

    1. Write an abstract aspect that contains abstract pointcut(s)
       denoting join points with the desired characteristics. Examples
       of such characteristics would be: needs transaction support, modifies
       state, performs time-consuming operation, needs authorization
       clearance, and so forth. The abstract pointcuts could form the
       aspectual interface for that aspect.

       The aspect also advises each pointcut or a combination of them with
       the required behavior. For above list of example, it would put the
       join point in a transaction context, notify the observers, surround
       with a wait cursor, and perform authorization checks.

    2. Each class that wants to participate in such behavior includes a
       concrete nested subaspect that extends the abstract aspect. Each
       such aspect simply provides the definition for the abstract
       pointcuts matching the needed join points in the enclosing class.
       The subaspects are free to define the pointcut in any way that
       suits their need: using regular expression, explicitly enumerating
       each method, or a combination of these.
       
       This way each class that want to be participate in the collaboration
       needs to do so explicitly; hence the name of pattern.

       Note that the concrete aspects need not be nested aspect of a
       class -- they could be peer, for example. Further, you may use one
       participant subaspect for a set of classes instead of just one
       class. The only important thing is maintaining a close connection
       between the participant aspect and the aspected core implementation.
       
    Comparing to JSR175-like metadata, the difference is the granularity
    is changed from method to class. In both case, the locality of
    meta-information is maintained.

    Here is an example:

    // Many details omitted...
    public abstract aspect TransactionAspect {
        abstract pointcut transactedOperations();

        Object around() : transactedOperations() {
            try {
                beginTransaction();
                proceed();
                commitTransaction();
            } catch (Exception ex) {
                rollbackTransaction();
            }
        }
    }

    public class Account {
        public void debit(/* args */) {
           ...
        }

        public void credit(/* args */) {
           ...
        }

        ...

        public static aspect TransactionParticipantAspect
            extends TransactionAspect {
            pointcut transactedOperations() :
                execution(* Account.debit(..))
                || execution(* Account.debit(..))
                || ...;
        }
    }

    public class ShoppingCart {
        public void addItem(/* args */) {
           ...
        }

        public void removeItem(/( args */) {
           ...
        }

        public static aspect TransactionParticipantAspect
            extends TransactionAspect {
            pointcut transactedOperations() :
                execution(* ShoopingCart.addItem(..))
                || execution(* Account.removeItem(..))
                || ...;
        }
    }

    If the Account or ShoppingCart class adds new methods or certain
    methods change their transaction management needs (say, due to
    refactoring), the nested TransactionParticipantAspect is all that
    needs to be change. Sicne the subaspects need to track the changes
    in the core class a close coupling between the two (by means such
    as the use of nested aspect) helps.

    One important implication of the participant pattern is that the
    core classes are no longer oblivious to the crosscutting concerns.
    However, their coupling is limited to defining the pointcut. But this
    is true with any approach using metadata.
  • public class ShoppingCart {

    > public void addItem(/* args */) {
    > ...
    > }
    >
    > public void removeItem(/( args */) {
    > ...
    > }
    >
    > public static aspect TransactionParticipantAspect
    > extends TransactionAspect {
    > pointcut transactedOperations() :
    > execution(* ShoopingCart.addItem(..))
    > || execution(* Account.removeItem(..))
    > || ...;
    > }
    > }

    With this approach, how do you specify the order between the tx-advice and the other system-advice?
  • With this approach, how do you specify the order between the

    > tx-advice and the other system-advice?

    You can use regular aspect precedence mechanism:
    aspect SystemCoordinator {
        declare precedence: TransactionAspect+, PoolingAspect, ProfileAspect;
    }

    The result is all subaspects of TransactionAspect (note '+'),
    the nested aspect in case of the example, get a higher precedence than
    PoolingAspect and both get a higher precedence than ProfileAspect.
  • Rickard Wrote:
    > One more thing: when I say "metadata" it's important to distinguish between the actual associations between classes/methods/fields and these attributes and how these associations are done. Using tags in source code is *one* way to do this, but certainly not the only one. As but one example, in our own AOP/metadata framework we allow attributes to be defined in XML-files which are read at startup and added to the set of runtime attributes gathered through source code doclet tags. This way we can have one set of attributes which are always the same (=defined in code) and some of which are more deployment oriented (=defined in XML). It seems like most people think "doclet tags" when you talk about metadata, but that's (to me) just one input method among others.

    Yes, we do the same in JBoss AOP Rickard. We provide a way to define metadata on a class outside the scope of the Java file. Declarative per-method, role-based Security is a perfect example class metadata in action. Metadata for generic aspects, yet the separation of concerns that some require.

    Bill
  • Easy learning AOP.[ Go to top ]

    I use JAC as my AOP framework.
    It may be slow, unmature or whatever (remember Java is slow :-). To me, it works and provides a solid and entertaining environment for AOP discovery.
    http://jac.aopsys.com
  • Great material. I have couple of comments on the interview.

    1. The figure example is less than ideal. It is a strange to me that after years behind AOP development we are still coming up with examples that poorly reflect real applications. In this example in particular, the two concerns are not so different or orthogonal after all. In fact, in many real applications with complex figures to draw not all changes to coordinates should require repaint. Furthermore, from the design standpoint it may be a better idea to require explicit redraw request by each figure to allow fine control over the redrawing (the major performance bottleneck in UI applications). So the point is that this example is very contextual and does not clearly illustrate two orthogonal concerns.

    Yet we have many examples that don’t suffer from the same deficiency: take Cedric’s example of how BEA uses AOP for unit testing, or take Bob Lee’s example of tracing the calls for debugging. Those examples leave no doubt that AOP is pretty much the only and the very effective solution for the problem and yet they demonstrate all the necessary basic principles. I sure there are many, many other “clean-cut” examples available.

    I think it’s very important to provide no-doubt examples when talking about such delicate subject as AOP.

    2. It’s important that it was clearly asserted that AspectJ requires a significant IDE support to be effectively used in any but simplest projects. The good news is that this is becoming lesser problem with IDEs like Eclipse and IntelliJ. However, it’s important to remember that one of the reason of why Smalltalk failed to gain any serious commercial support is that it required the entire environment (beyond IDE in many cases) to be functional.

    I think (almost sure) that for many developers IDE requirement will be a serious psychological barrier in adopting AspectJ or similar technologies.

    Granted, however, that IDE support dependency is not exclusively related to AspectJ but it’s rather AOP problem in general (at least for now).

    3. I think that future (mature) version of AOP (language, frameworks, etc.) would definitely support static and dynamic AOP as well as natively integrate with some form of declarative programming (whatever is available on a specific platform like Java or .NET). These are rather parts of overall AOP other than exclusive implementation venues and already now we are seeing many use-cases for each approach.

    Best regards,
    Nikita Ivanov.
    Fitech Labs.
  • IDE issue[ Go to top ]

    2. It’s important that it was clearly asserted that AspectJ requires a significant IDE support to be effectively used in any but simplest projects. The good news is that this is becoming lesser problem with IDEs like Eclipse and IntelliJ. However, it’s important to remember that one of the reason of why Smalltalk failed to gain any serious commercial support is that it required the entire environment (beyond IDE in many cases) to be functional.


    The Smalltalk and AOP IDE issues are completely different in degree.

    Smalltalk had a much more significant environment issue than we are talking about here. In Smalltalk the code was all in a repository, and you could not edit it, even briefly, any other way. You couldn't just fire up an emacs (or notepad) and edit the code. It wasn't that you would prefer not to do that because you would be missing the browser. You just couldn't do it, because the code wasn't stored in ascii files you could get at. Visual Age had this same issue, Eclipse does not.

    With regard to the degree AOP requires IDE support, I actually don't think this is any different than Java. You can program Java in old-fashioned non-extended emacs. But, having support for automatically reminding you what methods a type accepts, what order the arguments are in and the like makes it much easier. Being able to quickly see the Javadoc for a method makes it easier. Being able to quickly see a class in the structure browser makes it easier. So most people use a tool with Java support most of the time, be that Eclipse, JBuilder, java-mode or whatever.

    The exact same thing is true of AspectJ. You can program it in old-fashioned non-extended emacs. But, because aspect is almost entirely just Java, all the reasons above make it easier to use an editor with Java support. And because AspectJ adds crosscutting structure to Java's hierarchical structure there is one more reason to want structure browsing support. So, most people use a tool with AspectJ support. But you don't have to have it.
  • IDE issue[ Go to top ]

    Having written AspectJ code both ways: non IDE and in-IDE, I agreee with Gregor. It's possible (even very possible!) without, but much nicer with.

    I think theissue of "I can't use my favorite plain Java tool to develop in AspectJ" is larger than "I need to use *some* tool to develop in AspectJ." Given the strong support that AspectJ is recieving from various IDE development teams, I anticipate that this will also be a non-issue.
  • The figure example is less than ideal. It is a strange to me that after years behind AOP development we are still coming up with examples that poorly reflect real applications. In this example in particular, the two concerns are not so different or orthogonal after all.


    Actually, one of the good properties of the figure example is that the concerns are not 'orthogonal'. Few real interacting concerns are orthogonal. Instead the concerns interact, and part of the goal of modularizing the concerns is to clarify the way they interact. In AspectJ, one thing poincuts do is show how crosscutting concerns interact.

    > In fact, in many real applications with complex figures to draw not all changes to coordinates should require repaint.

    Right. That's another thing that is good about this example. It shows that having modularized the updating functionality, those kinds of changes become easy and local. For example, if you want to pass the update code the figure element that moved you change the aspect to:

    pointcut stateChange(FigureElement fe): <old pointcut> && target(fe);

    after(FigureElement elt) returning: stateChange(elt) {
      Display.update(elt);
    }

    Or, if you want multiple observers per figure element, you change the advice body to:

     notifyObservers(fe.getObservers(), fe);

    Or, if you want to prevent updates from recursive state changes, then you write:

    pointcut topLevelStateChange(FigureElement fe):
            stateChange(fe) && !cflowbelow(stateChange(FigureElement));


    Or other conditions can be written. Because they are modular, its easy to understand the crosscutting display update policy.
  • Implicit vs. Explicit[ Go to top ]

    Here are my 2 cents...
     
    I see several trends in this thread in regard to implicit vs. explicit metadata-based pointcuts and to whether regexp support is useful or not. I _strongly_ agree with Rickard Oberg’s assessment about attaching certain behavioral semantic to a method (e.g. @ReadOnly) via metadata attributes and then having advises applied to all methods with identical behavioral semantic. This approach is explicit and readable and strikes no questions in developer’s mind in regard to any hidden behavior in the method.

    Explicit metadata approach is also OK to use for concerns that are not purely orthogonal since metadata attributes show developer’s awareness and willingness to accept such concerns. For instance, if metadata attribute is @TransactionRequired, then such attribute confirms that developer was mindful to include any _extra_ rollback or recover handling before an exception is thrown, or if the attribute is @ReadOnly, then such attribute confirms that developer is mindful that the method does not change any state now and will not change any state in future when this code is maintained by others. Explicit approach goes well with notion of _conscious coupling_. By attaching metadata to methods developer in some way manually endorses all AOP hooks that can be attached to these methods thereafter.

    With implicit XML-based metadata or, what’s even worse, regexp-based approach, developer has no idea as to what type of behavior may be attached in future to any method. Such approach would be safest to use with _pure_ orthogonal concerns, i.e. the concerns that will _never_ require any developer’s awareness about potential advised behavior that can be attached to a method.

    Regards,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Technology for Java and .NET
  • Implicit vs. Explicit[ Go to top ]

    \Dmitriy Setrakyan\
    Explicit metadata approach is also OK to use for concerns that are not purely orthogonal since metadata attributes show developer?s awareness and willingness to accept such concerns. For instance, if metadata attribute is @TransactionRequired, then such attribute confirms that developer was mindful to include any _extra_ rollback or recover handling before an exception is thrown, or if the attribute is @ReadOnly, then such attribute confirms that developer is mindful that the method does not change any state now and will not change any state in future when this code is maintained by others.
    \Dmitriy Setrakyan\

    Your two examples are quite different in my mind.

    "@ReadOnly" would not mean that the developer is mindful of anything - he's making an explicit declaration that "this code does not mutate the object state".

    "@TransactionRequired" does not say anything about the code you're looking at. It's a request that something else somewhere add transaction capability.

    The difference is in your statement "confirms that developer was mindful to include any _extra_ rollback or recover handling before an exception is thrown".
    How, exactly, is the developer supposed to do this? He's a POJO, he implements no interfaces, and hasn't the slightest idea how to get a hold of the current transaction or transaction manager. For example, if a non-exception error condition should result in rollback, there's no way for the poor bugger to tell anyone of that fact.

    \Dmitriy Setrakyan\
    With implicit XML-based metadata or, what?s even worse, regexp-based approach, developer has no idea as to what type of behavior may be attached in future to any method. Such approach would be safest to use with _pure_ orthogonal concerns, i.e. the concerns that will _never_ require any developer?s awareness about potential advised behavior that can be attached to a method.
    \Dmitry Setrakyan\

    A pointcut does not magically appear in the system and start mucking about your code structure through advice. Someone has to write that pointcut, and someone has to write that advice.

    From what I've seen of something like JBoss AOP, all/much of this is hidden from you, and that _is_ a bit frightening. In a more generalized approach where application developers themselves are using AOP, it's an entirely different proposition - and this is doubly true if you're using AspectJ. There, you might write regular POJOs in your primary domain, and then write aspects to encapsulate "extra" behavior. In such an approach, your POJOs stay largely (or completely) pure POJOs, and your aspects are built to interact with them to build in additional "cross-cutting" behavior. These aspects may be highly generic and orthagonal, or they may be tightly coupled to your primary classes (coupled, but the behavior is still seperated at).

    For example, you might have an abstract TransactionAspect, and you can extend this to pick out what classes (and methods within them) are transactional. You can further make highly specialized aspects for special cases - like a POJO that has some special needs when you're considering transactions, and where you might need markRollbackOnly() behavior. Such behavior would be implemented in an aspect that is seperate but closely associated with the POJO.

    How you define such concrete transaction aspects is up to you, but it might heavily rely on meta-data like "readOnly" and similar design notes to help select where to apply transaction code. Your aspects may also specifically single out classes/methods for transactionality (again, maybe with help from meta data to figure out semantics in a more concrete manner). These aspects may use a generic abstract TransactionAspect, and optionally give very specific and coupled behavior for special cases. And best of all, with AspectJ this can be done in a statically type checked manner, and your concerns are _truly_ seperated out and easy to track. And the developer always has control over what's going on.

    On top of everything else, your transactional POJO can be re-used in other contexts with other cross-cutting concerns (either in the same app or other ones) without invasively adding code/meta-data directly to the POJO. To use an example that comes up often with me - lots of time, code is initially developed in an app server, like Websphere or Weblogic or what have you. There's nice app software layers and all that. Eventually, stand-alone processes need to be created which need to re-use a subset of the overall functionality. For example, a trading system may have a nice instrument/price domain model which is used in the app server middle tier, and you may have need to bulk-load instrument/price info in a seperate process taking a feed from elsewhere. These are two very different uses of the same domain model - trade processing in the app server, and bulk-loading from a special stand alone app. However - this is often difficult because the domain model has tons of crud within it dedicated to secondary concerns for working in the app server, but which is of zero help inside of the bulk-loader. In such a scenario, your bulk loader and app server middle tier app can both use a clean domain model, and use external aspects to add in behavior appropriate to the context. If you're using meta-tags buried directly in the domain model, you're locking it into one usage context that may make zero sense to another one.

         -Mike
  • Implicit vs. Explicit[ Go to top ]

    <Mike>
    "@ReadOnly" would not mean that the developer is mindful of anything - he's making an explicit declaration that "this code does not mutate the object state".
    </Mike>

    @ReadOnly attribute means that developer has _purposely_ made an effort to avoid changing state in the method. It is a readable and declarative way for a method to pledge read-only behavior, so all aspects triggered by this attribute will only assume immutability of state and _nothing_ else.

    <Mike>
    "@TransactionRequired" does not say anything about the code you're looking at. It's a request that something else somewhere add transaction capability.
     
    How, exactly, is the developer supposed to do this? He's a POJO, he implements no interfaces, and hasn't the slightest idea how to get a hold of the current transaction or transaction manager. For example, if a non-exception error condition should result in rollback, there's no way for the poor bugger to tell anyone of that fact.

    </Mike>

    I don’t know if developer has or should have a handle on current transaction or not... Such assertions should be different across projects and application requirements. If it’s possible for non-exception error condition to trigger rollback, then _mindful_ developer should get a handle on current transaction and call setRollBackOnly() on it. It would be interesting to see how you propose to solve it without interaction of _mindful_ developer.

    In regard to your trading example, seems like you are talking about a pure orthogonal concern, i.e. domain objects are absolutely not aware and, more importantly, don’t even care whether they are used in the middle tier or loaded from data store. In such case, metadata may not even be useful at all and definitely shouldn’t be explicitly attached to domain model code. Moreover, it’s questionable at best if concern you are describing will ever be _purely_ orthogonal in real life, and whether it is best solved with AOP rather than OOP based techniques.

    Regards,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Technology for Java and .NET
  • Pointcuts and Metadata[ Go to top ]

    I've enjoyed the discussion on pointcuts and metdata and their uses in
    AOP. I think the well-designed pointcuts should describe something
    fairly abstract that is happening in the system. These should not be
    describing how they will be used.

    The implementation should be the most robust way to capture the
    design, i.e., minimizing the maintenance effort and reducing the risk
    of incorrectness. In descending order of robustness, I believe the
    implementation options are:

    1) precisely capturing the definition. Today, this fits where
       properties public methods or all subtypes of a class match the
       concept. As AOP matures, I believe there will be richer pointcuts
       so this category grows. E.g., a readOnly method is one that does
       not set any (non-transient) fields, nor call any non readOnly
       methods.
    2) reliant on stable frameworks (e.g., in a servlet response or a
       Struts action) or organizing principles (e.g., package organization
       conventions).
    3) reliant on widespread naming conventions. This approach is already
       commonly used in component development (e.g., JavaBeans naming
       pattern matching resulting in automatic behavior enforcement, or
       Weblogic Workshop or VB using method naming for event handling).
       Indeed, (static) AOP improves on this by providing good tools
       support to see matches and track changes. There is also the promise
       of refactoring support that will alert the developer to potential
       problems, unlike traditional approaches with specialized tooling.

    These first three are all highly stable and avoid the fragility of marking every
    instance of something.

    4a) inline annotation through attributes (metadata). This is best for
        general-purpose concepts that are closely coupled to the core
        design. In this case, the use of attributes will be the best
        option. Forcing the use of an obscure naming convention is the
        worst option (it's better to use the participant pattern or
        external enumeration in the absence of attributes).

    4b) external enumeration of matching points. If the concept is
        special-purpose, or really a choice about configuration or
        deployment (i.e., orthogonal), then the enumeration should be done
        separately to avoid tangling concerns.

    To me the choice between 4a and 4b is parallel to that between
    attributes and deployment descriptors for J2EE 1.5. For items that are
    core to the design, adding a generally descriptive attribute is
    preferable. For choices that should be bound after the code is
    written, the external enumeration is preferable. Whether this
    enumeration should be made in aspect code or XML is a separate debate.

    5) To be avoided: "tricky" regexp's, including naming patterns that
       are obscure or unexpected. I think it is cases like this that
       critics of regexp pointcuts have in mind.

    In some cases, the general-purpose definitions are only "mostly
    right", and one can use enumeration or attributes to identify
    exceptions to the rule (e.g., Timer.settings() isn't a setter). This
    can be done by configuring abstract aspects for a particular component
    or system. E.g.,

    public abstract aspect TransactionManagement {
        /** defines executions of read only methods */
        public pointcut readOnlyExecutions():
            (execution(* get*(..)) || execution(* is*(..))) &&
            !readOnlyExceptions() && inScope();

        /** defines exclusions to the normal rules for
            read only methods */
        abstract pointcut readOnlyExceptions();

        /** defines the scope of application of the instantiation of
            this pointcut */
        abstract pointcut inScope();
    }

    I also think that AOP support for JSR-175 should include static
    crosscutting. E.g., adding declare attribute to AspectJ, to be
    used in a superset of cases of when one uses declare parents
    with marker interfaces today. Cedric: I agree that marker interfaces
    will be obsolete when we have real attributes. This provides an
    interesting opportunity to allow developers to mix and match
    enumeration and in line descriptions, as Adrian Colyer pointed out.

    Cedric and others raised the question of good examples of robust
    concepts for pointcuts ("annotated concerns"). Here are a few
    suggestions that represent interesting points on the spectrum:

    1. Security: sensitive information (objects), personally identifiable
    information (objects), restricted function (methods). These are
    meaningful concepts independent of the security policy in effect. One
    can write very different advice for them (access control, audit
    trails, personalization to filter unentitled links, statistics on
    access, etc.).

    Sometimes these items can be identified by package structure, but they
    often need to be identified explicitly. In this case, external
    enumeration is preferable to inline annotation because classification
    of information can change more frequently and independently of
    application logic, and because it's highly desirable to separate
    specification of security from business logic.

    Methods that access sensitive data are very much like transactional or
    readonly methods: ideally it would be handled by tracking methods that
    handle a given type of data. Today, these are best
    enumerated. However, with AOP, it is more feasible to defer
    enforcement to the point of access rather than pre-emptively
    restricting access, logging, etc. (i.e., this derivative concept may
    not be required for correct policy implementation).

    2. Error handling: Policies for logging, converting, displaying, and
       resolving exceptions typically use very stable well-defined
       concepts. E.g., convert exceptions when exiting a tier (a top-level
       public methods within a group of packages) or log and handle within
       framework elements (e.g., Action classes or other controllers or
       Runnables).

    3. Template classes. This is a domain-specific example from a project
       where we need to persist historical values of certain "template"
       objects (but not the derived objects). Tracking which classes are a
       template is a more general idea than object versioning. The concern itself
       would be natural to annotate inline with attributes.

    4. Framework operations. E.g., J2EE pointcuts. This kind of pointcut
       is very robust and is applicable for a wide variety of concerns
       (e.g., to define accesses to session information while servicing a
       servlet).

    5. Testing. There are a number of different kinds of pointcuts that
       are interesting for testing when enhanced by AOP. It's often
       important to test whether one is in test code (to enable tracing,
       change behavior, or not affect the test code itself).

       a) In a test case: This can be defined structurally (e.g., a
       subtype of a TestCase).

       b) In a testing stub: This can be defined robustly with clear,
       common naming standards (Test* or *Stub), with specific packages
       (*.test).

       c) Operations to be replaced with mock processing. If one is using
       "virtual mock objects", it's important to define where mock
       processing applies. This is basically a combination of a structural
       property (in the control flow of a test case) and external
       configuration information (within a given test case, affect
       processing of these specific objects). So these should use
       pointcuts that combine universal definitions with ones that provide
       specific enumeration.
       This seems like a natural use for dynamic AOP; eventually I'd like to
       see a combination of the configuration capabilities of a Polygenix
       with the power of AOP.

    8. Development instrumentation (debugging, profiling, tracing): This
       needs to be defined externally from the code. It's
       deployment information, not intrinsic to the design.

    Ron
  • Another hype to crash projects??[ Go to top ]

    It is amazing how easy it is for some people to make some side effect or some programming behavior become the "Mother of All The good things"...Here comes another Unified Proccess, another "bet-it-all-on-UML ", another "Extreme programming kicks behinds", to confuse more developers and to help projects crash by wasting more time in anything else but implementation...

    Final proof: Ivar Jacobson is also behind this...

    Please people, don´t let them confuse you once more...
  • kara you are missing the point[ Go to top ]

    every technique has its limitations, and every technique is only as good as its user.

    with that in mind, you should have no problem with RUP, UML, XP, OOP or AOP

    joe
  • Well, I'd agree with Kara, at least partially. Here comes another paradigm, another new way of thinking. And we already have so much to think about when creating systems... I´m sure most people could handle another "bunch" of new concepts, and also that they are coming for our best, to help us design better systems. But I wonder where will it stop, since every new concept add to the complexity of systems development, thus making things harder and harder. I just don't want things to get to a point where all developers must be Phds in something just to write the next notepad...

    Take this from someone who hates M$'s over-simplicity-ness, like VB and ASP.

    Besides that, I realy see that the separation of concerns can help us. Just don't forget KISS. Maybe it would be time to create an "AOP study group" thing, so this could be discussed more properly than in forums. It's clear that this new powerful concept has room to grow and mature, until it finds its place in everyday's work in development. Like OOP did years ago.
  • The last thing that J2EE projects need rigth now is another "invented" complicated paradigm to add to the picture. Let´s stop doing things more and more complicated, let the j2ee arena rest for while, let´s get tools up there to consistent and mature productivity and lets stop going much faster than what we need.
  • Well, everything in computing is invented - it's not a natural science where you're discovering some principal of nature. Every language and tool has sprung mostly from the fertile imagination of plain old people.

    Flowery words aside - many of the leading people I've seen advocating AOP are advocating a slow adoption approach, and usage within J2EE is only just now even being considered by the leading edge. As I've said in other threads - going with something like AspectJ isn't like a switch from C++ to Java. It can be very gradual, and 99.9% of your code can be pure Java, with a touch of aspects to ease you into the waters. This is precisely what I'm doing now - playing around with AspectJ in development, and using it as an advanced debugging and testing tool. And it's not part of any standard, so no one is being forced into it. My own work is similar in spirit to what BEA has provided for Weblogic - an additional tool that can make certain tasks much easier, but isn't part of the core that you need to worry about if you don't want to.

    The true controversy is JBoss using AOP as the basis of its own internal framework for many new features. In that realm, you may encounter alot of limited AOP which may be a bit of a shock to developers new to it. The aim appears to be to make this as transparent to normal users as possible, but I suspect, AOP will seep more and more into user's code.

        -Mike

  • > The true controversy is JBoss using AOP as the basis of its own internal framework for many new features. In that realm, you may encounter alot of limited AOP which may be a bit of a shock to developers new to it. The aim appears to be to make this as transparent to normal users as possible, but I suspect, AOP will seep more and more into user's code.
    >
    >     -Mike

    For standard users of our J2EE-based application server, the introduction of AOP into the codebase will not have an effect on their development. The real power of AOP, we hope, in EJB land will be with the ISV and tool vendors themselves as they can have a tighter integration with JBoss rather than relying on cumbersome code changes that can get out of synch with the HEAD CVS of JBoss.

    JBoss AOP also has the same separation of concerns that other AOP frameworks have. You have your pojo and you define your pointcuts in an XML file. Simple as that. Your advices are defined as Interceptors as pure java objects and defined/attached in the same XML file.

    Bill
  • Any technique that targets 80% methodology and 20% implementation is far from being good no matter how good its user is...
  • Any technique that targets 80% methodology and 20% implementation is far from being good no matter how good its user is...


    I agree Kara, let's keep those that are code-alergic from our code.

    I disagree though, that AOP is all about methodology and little about implementation. AOP has a strong place in our development process. If you look at all the new frameworks that are coming are appearing at Apache.org, JBoss.org, and other cool projects like Hibernate, you'll see that they are POJO based, and POJO centric. Meaning, you write plain java objects and attach the functionality you want to attach via some descriptor file or such. This is where I believe will be the first place AOP will be adopted. By the framework developers. AOP gives these framework developers a standard way to apply their technologies to simple object models.

    Bill
  • kara you are right to the point[ Go to top ]

    I sort of agree. The main problem of IT projects it that they struggle to cope with compexity. So basically, you would strive for a tool that reduces complexity.

    AOP claims to do this, but I am quite sure that it creates more complexity than it reduces. Consider that there might be reason why the number of premium CLISP programmers is limited. Hint: It is not the lack of projects, it's rather that certain language constructs, while boosting *productivity* for the ones who are able to handle them, add a lot of complexity for those who don't. Complexity is not only in the number of lines of code but also in the effort needed to understand the "what happens if" of a piece of code.

    Considering the complexity of a tool like AspectJ and letting it loose on your average project team - remember most "OO" programmers are still struggling to understand polymorphism -- frankly it sort of worries me. Another point that worries me is that there still is no common base that might define what "AOP" actually is. No first class textbook that defines "point cut", "AOP", "join point", "aspect" or "concern" etc.
  • AOP Complexity[ Go to top ]

    Believe it or not, I share your concerns about AOP complexity in an IT environment. Java has been great on many projects I've worked on because it's so simple and straightforward that the team tends not to have to fight the language very often (although there are some who seem doomed no matter how simple the language is :-). In general I value simplicity and am automatically suspicious of "cool" things that add complexity into a system. Usually the payoff isn't worth the complexity draw backs.

    I certainly felt like that about AOP when I first ran into it. I imagined some of the people I work with having the ability to intercept random code at runtime and add in new behavior, and shuddered violently at the idea. It felt about as appropriate as giving a gatling gun to an 8 year old.

    Deeper research and experimentation with various AOP frameworks has somewhat changed my mind, though. Many implementation approaches in Java are very tedious and even more error prone, and can lead to alot of code obfuscation and maintenance problems. And I've found AOP is directly on point for many of those issues, and can help eliminate complexity.

    And in particular - I've found AspectJ strikes a good balance between power, usability, and maintainability. Many features of AspectJ aren't there to give you more power over "foreign" code that you're adding aspects to - instead, those features are there to constrain your use, help keep it modular, and to better track problems as they arise. In a nutshell alot of the real nasty possibilities of AOP are pretty well contained within AspectJ.

    Still, there is still without a doubt more complexity involved in its use (syntactic, structurally, and in imaginging the runtime consequences), and there's a large minority of developers I would never, ever want to expose AOP to, because they just wouldn't handle it properly. But I think the balances in AspectJ, and the features it gives me, are worth the complexity and risks in the long run.

        -Mike
  • IBM & AO?[ Go to top ]

    Gregor says "IBM is making significant investments in AOP". I'm wondering if this refers to Hyperspaces and Hyper/J or if IBM is doing something else in this area.

    groeten uit nederland,
    Joost
  • IBM & AO?[ Go to top ]

    IBM is indeed investing in a successor to the Hyper/J work, known as the CME.

    We are also contributing significant resource to AspectJ. Since its inception, the AspectJ Development Tools project (AJDT) has been run out of IBM's Hursley lab in England. I've been a committer on the core AspectJ project too since it moved to Eclipse, and took over from Jim Huginin earlier this month as the overall lead of the AspectJ project. Some of our internal work using AspectJ has been published (see e.g. the practitioner report on the AOSD 2003 conference website, and a forthcoming practitioner report at OOPSLA 2003), and I hope that we'll be able to speak publically about a whole lot more soon.

    Whilst on the surface it may look strange for IBM to be doing both of these things, the two teams work closely together and we have used AspectJ together with some early components of the CME on internal projects to good effect. Thus we see the approaches as complimentary rather than competing.
  • Non-system-level AOP usecases[ Go to top ]

    I'd like to see some usecases of something other than system-level aspects. The only one good example I could two I could think of is:

    The Observer pattern. Being able to transparently listen to events (like a method bing called) without have to implement a Listener interface.

    Hard core usecase: Maybe billing on a B2B service. Billing as it pertains to method, user credentials, etc.... Am I making any sense here?

    Bill
  • Non-system-level AOP usecases[ Go to top ]

    I'd like to see some usecases of something other than system-level aspects. The only one good example I could two I could think of is:

    <snip>

    Well, if I look at the code of our own CMS product which is built with AOP, I can see (roughly) three classes of advice and mixins. There's the system level, and the application level, but also some in between, which would be orthogonal to the domain but still on the application level (e.g. parent/child relationships, ACL's, linkable etc.). The majority of mixins are on the application level, and the majority of advice are on the system level.

    As for advice that are on the application, in our code there are mainly two categories of them: 1) most are related to lifecycle side-effects, which basically has to do with creating and removing aggregated objects and 2) some are related to dealing with parent/child behaviour in tree graphs (remember it's a CMS, so we have lots and lots of tree graphs). Basically each object type (and I don't want to use the word "class") has its own lifecycle advice, and some have specialized parent/child behaviour.

    So, that's the case in our application at least. YMMV.

    /Rickard
  • Non-system-level AOP usecases[ Go to top ]

    I'd like to see some usecases of something other than system-level aspects.

    > The only one good example I could two I could think of is:
    >
    > The Observer pattern. Being able to transparently listen to events (like a
    > method bing called) without have to implement a Listener interface.
    >
    > Hard core usecase: Maybe billing on a B2B service. Billing as it pertains
    > to method, user credentials, etc.... Am I making any sense here?

    Billing is a good example, to my point of view. As there are business rules in general.

    You can describe billing functionality independent of its instantiations in terms of participants such as LineItem, Customer, Product, PriceBuilder, etc., and some basic interaction among these participants. However, when it comes to implementing billing for a concrete application, you will have to distribute the functionality around the classes that play the respective roles in your application and methods in those classes that billing pertains to.

    With aspects you can modularize billing functionality, by saying which points in your application's execution should trigger some billing functionality and how billing is performed. Now, why do you want to do this? Well, billing can apply in different places of your application, or you can have different billing policies (e.g., sales pricing, frequent customer pricing, etc.), with different classes in your system playing the billing roles, Item, Customer, etc. And, you might even want to change your billing policy depending on the context of use. Once you have modularized billing in one aspect, adopting a new billing policy is a matter of changing the pointcut specification in the aspect. You can even have an abstract aspect defining the generic billing functionality which can than be instantiated in different ways in concrete aspects.

    Mira
  • Implementing business rules is an interesting use of AOP that allows noninvasive enhancements to system functionality. Since you can change the rule evaluation mechanism by simply changing the rule aspect, the AOP approach allows a reduced emphasis on the rule implementation details during the initial design phase without sacrificing the ease of system evolution. For example, you may initially use plain Java for rule evaluation and later switch to a rule engine such as Jess by just modifying the aspect. You can even switch from a rule engine to another without any changes to the core classes.
     
    As Mira points, the advantages of using AOP include modularity and ease of evolution. These properties help to keep the core stable even when the business rules, which tend to be more volatile, change. For systems that already implement business rules in conventional way, the use of AOP offers an additional dimension for refactoring.

    -Ramnivas
  • <quote>
    For example, you may initially use plain Java for rule evaluation and later switch to a rule engine such as Jess by just modifying the aspect. You can even switch from a rule engine to another without any changes to the core classes.
    </quote>
    Only because of changing implementation you don't need to use aspect. Just use "Interface" and "Implementation". You can change the implementation as long as you use the same interface. This is an example of "over using" aspects, IMO.

    Aspects should be used for cross cutting concerns. Without this, you can already using design patterns and OO. Back to the billing example. Is that true that using aspects for billing functionality could make my business application easier to understand, easier to extend? Just like the AspectJ simple example of "Display.update"?

    I'm curious, are there any business applications (Oracle, PeopleSoft, BAAN) using aspects or AspectJ to extend the business functionality (example like billing functionality, tax calculation are very good one ;-))? Thanx!

    Regards,
    Lofi.
  • I agree with you that if business rule implementation were not a crosscutting concern, use of AOP would be overkill. However, it is definitely a crosscutting concern; populating working memory and evaluating rules cut many modules in a system. Typically you would need to advice many important methods in you system to perform these activities.

    Creating a good set of interfaces so that you can replace one implementation with another one is a complex process—the one that requires enough foresight, a good understanding of at least two possible implementations, time, and resources. Therefore, most projects perform the step of defining interfaces for core prominent concerns only.
     
    Let’s do a thought experiment: Consider a situation where you need to implement business rules and you have determined that Jess as the rule engine satisfies your current needs. What would be your first step? Understand the abstract nature of the rule engine API and write a set of interfaces? Then write a concrete implementation of those interfaces to delegate the actual work to Jess? How comfortable would you be that this API is good enough to implement using another rule engine’s API? Or, would you simply use the Jess API directly?

    Consider another example, something that many would have experienced already. When log4j appeared first, how many projects spent time to first define an abstract logging API (such as Jakarta Commons)? Not many, I know. Most just used the log4j API. Later came the standard Java logging toolkit. And only then came Jakarta Commons. Still not many use Jakarta commons either.

    For crosscutting concerns, AOP allows the same flexibility you would gain from the use of interfaces as you describe without paying an upfront cost of developing those interfaces. Of course, if you do have well defined interfaces, by all means, you should use them from you aspect’s code. Then you don’t need to change even the aspect when you change the underlying implementation.

    -Ramnivas
  • Aspecs as cooperative code[ Go to top ]

    You've touched on what I consider one of the more intriguing uses of AOP - using Aspects in a cooperative manner to augment your "primary" classes. It's not as glitzy and marketing friendly as making a POJO transactional with zero extra code, but the idea of writing aspects explicitly to support a specific code base is incredibly useful, and leads to _alot_ of modularity and the ability to switch implementation decisions quickly and safely. It's not sexy, but it makes my own job quite a bit easier based on the baby steps I've taken with AspectJ so far.

        -Mike
  • Aspecs as cooperative code[ Go to top ]

    In Gregor’s interview a quote from Adrian Colyer points to such usage of AspectJ. I too find myself using a lot of such aspects for implementing local concerns ranging from lazy-initialization of fields, class-specific exception handling, simple caching, class-specific policy enforcement to good-old debug tracing. In every case, the resulting implementation is modular and clearly shows the design intention. Since these aspects tend to be very restrictive in parts they crosscut (typically through use of within() pointcuts), they do not affect unintended classes. As a matter of style, the use of nested aspects inside the primary class shows their strong coupling and makes modifying the aspects to track changes in the enclosing class an easier task.
  • Business Rules[ Go to top ]

    <quote>
    Let’s do a thought experiment: Consider a situation where you need to implement business rules and you have determined that Jess as the rule engine satisfies your current needs. What would be your first step? Understand the abstract nature of the rule engine API and write a set of interfaces? Then write a concrete implementation of those interfaces to delegate the actual work to Jess? How comfortable would you be that this API is good enough to implement using another rule engine’s API? Or, would you simply use the Jess API directly?
    </quote>

    Yes, this is always a difficult decision. I myself prefer to build those interfaces (adapter) to the Jess API like what these articles show:
    "Implement business rule engines in a J2EE enterprise"
    http://www.javaworld.com/javaworld/jw-09-2002/jw-0906-process_p.html and
    http://www.javaworld.com/javaworld/jw-10-2002/jw-1018-process2_p.html

    The question is, what would be easier to maintain in the long term? Anyway, we'll have JSR 94: Java Rule Engine API (just like JDBC) so it's not necessary to write the adapter first. BTW, we were talking about "non-system-level of AOP". Changing implementations of the rule engine (eg. product X instead of Jess) and not the business rules itself (eg. sales pricing, frequent customer pricing) is IMO a system level area ;-)

    Regards,
    Lofi.
  • Business Rules[ Go to top ]

    Anyway, we'll have JSR 94: Java Rule Engine API (just like JDBC) so it's not necessary to write the adapter first.

    JSR-94 isn't "just like JDBC". It lacks a standardized command language such as SQL. Each vendor's rule engine has its own proprietary rule language. JDBC supports portable relational schemas, but JSR-94 doesn't support portable rules. Without rules portability, there's no skills portability. Very different from JDBC.
  • SRML[ Go to top ]

    <quote>
    JDBC supports portable relational schemas, but JSR-94 doesn't support portable rules. Without rules portability, there's no skills portability. Very different from JDBC.
    </quote>

    Therefore you have Simple Rule Markup Language (SRML):
    http://xml.coverpages.org/srml.html

    Check out the articles I mentioned above.

    Regards,
    Lofi.
  • Business Rules[ Go to top ]

    Anticipating someone saying JSR-94 (which is still not yet complete), I posed log4j-standard logging toolkit-Jakarta Commons example. :-) This is one example, where you can go back and see for yourself what you *did* and not how it could have been done. Even with rule engines, what would you have done 3 years back (when JSR-94 activity just started)? You had two choices: create your own abstract API or wait for the completion of JSR-94 and support from the vendors.
     
    JSR-94 is a good example of complexity involved in creating an abstract API; just see how long it is taking rule engine experts to come with an API that is sufficiently abstract to allow multiple implementations and still remain useful. If the main task is to create a business application, I doubt how many projects can afford to spend time and resources on creating such abstract APIs by themselves (assuming they have expertise to do so).

    Don’t get me wrong. I favor of using abstract API when it is available, whether you use AOP or not. When JSR-94 becomes available, you should use it, whether you use AOP or not. I even favor creating such APIs for core parts of your system. However, do consider what AOP is offering here. It will save you time and resources, while offering you a safer path to switch underlying implementation.

    -Ramnivas
  • Non-system-level AOP usecases[ Go to top ]

    <quote>
    Billing is a good example, to my point of view. As there are business rules in general.
    </quote>

    Surely we can also use "Policy" design pattern to solve this problem as described in SanFransico Design Patterns - Blueprints for Business Software, from James Carey, Brent Carlson and Tim Graser (This is a great book for everyone who wants to write OO business applications).

    This is actually the problem with aspects in non-system-level I've seen until now:
    - I haven't seen any use case that shows some "value adds" of using aspects instead of just using available design patterns.
    - I've read an article from SAP about how SAP defines "adding business facilities/functionalities" in their business software, they do not seem to take advantage of aspects. They use a method what they call "Java Business Add-Ins" (BAdI). They use a combination of some design patterns: Registry, Factory, Proxy, Handler and Implementation (black-box extension). In general they define the so called "extension points" to be extended by any interface implementations. It seems that the independency of the extensions and the application itself is the most important factor. As you can imagine if a new SAP version arrives, all the SAP customers should easily upgrade the software without having problems with their own extensions.

    Regards,
    Lofi.
    http://www.openuss.org
  • Non-system-level AOP usecases[ Go to top ]

    \Bill Burke\
    I'd like to see some usecases of something other than system-level aspects.
    \Bill Burke\

    This is going to come out much nastier than I intend, but it's the only way I can think of to say it.

    "Try buying a book on AOP".

        -Mike
  • Not a toy example[ Go to top ]

    I think Bill is not talking about some "toy examples"

    Pratheep
  • Not a toy example[ Go to top ]

    Neither was I. Pick up some of the more recent AspectJ books, and some more recent papers on AOP, and you'll see tons of real world examples.

    Incidentally, his example of "Observable" is covered in Mastering AspectJ, which in turn references the design-patterns library for AspectJ.

    The moral of the story being that researching a subject in depth is a great way to avoid "discovering" a "new" technique that is in fact described in detail in the literature. It also, incidentally, avoids alot of embarrassment and misunderstanding, and recreating others' mistakes from the past.

        -Mike
  • Automatic patterns.[ Go to top ]

    Incidentally, his example of "Observable" is covered in Mastering AspectJ, which in turn references the design-patterns library for AspectJ.

    AOP and MDA are both kicking booty on pattern automation. And they're complimentary. For example Shlaer-Mellor "coloring" makes use of both declarative aspects and code generation templates.

    Those who claim that code generation is a bad "design smell" might rightfully note that data driven is cleaner. The good news is that MDA can use AOP to drive execution by data rather than code.
  • Non-system-level AOP usecases[ Go to top ]


    > This is going to come out much nastier than I intend, but it's the only way I can think of to say it.
    >
    > "Try buying a book on AOP".
    >

    Mike, the funny thing is that there is no first class textbook on AOP. I have read a couple of books on AspectJ and they even fail to give a clear and abstract definition on what are pointcuts, an aspects, concerns, join points, advices and how they relate. This is *very* unlike where OOP was conceptually say 1975. Implementations and frameworks also mix these concepts rather freely - an advice to one is a concern to the other etc. This gives me the feeling that people look for a way to mess around with code execution path and class hierachy at runtime and wrap it in a whole lot of AOP fluff. And I agree it is useful sometimes. As with the "business" or "real world" examples. Sure the books give this stuff but for business AOP to work in the simplest of business cases like authorization you need to have *a lot* of white box knowledge about what is going on. You soon end with implementation rules like:

    "No public method may ever be called from another public method if the same type of concern (whatever that is, but lets say authorization) is likely to be imposed on those methods. No concern may act on a method or class that is not public"

    This on the other hand leads to development of public methods as proxies for implementations for the sole purpose of being the target of a concern which in turn must be referred to as scattering......
  • Non-system-level AOP usecases[ Go to top ]

    \Karl Banke\
    Mike, the funny thing is that there is no first class textbook on AOP.
    \Karl Banke\

    Not being a deep comp sci person, lack of textbooks doesn't faze me very much (I doubt there's a "textbook" on perl but I find it quite usable). The existing books, particularly the newer ones that came out this year, are quite good IMHO.

    \Karl Banke\
    I have read a couple of books on AspectJ and they even fail to give a clear and abstract definition on what are pointcuts, an aspects, concerns, join points, advices and how they relate. This is *very* unlike where OOP was conceptually say 1975.
    \Karl Banke\

    I responded to this in another thread - what I thought the definitions of the above were - and you never followed up.

    Pointcuts, jointpoints, and advices are extremely well defined, and I've yet to meet a person who _really_ read an AspectJ book not understand what they mean.

    "Aspects" and "Concerns" are more difficult. An aspect is as loosey-goosey in its definition as a Class is in OO - it's mostly just for defining your boundaries. A concern is pretty much entirely an abstract concept - just like you don't see "requirements" in code, just an implementation which reflects those requirements.

    As for "where OO was conceptually say in 1975" - I hope you're joking. OO was very, very badly understood in 1975 with very, very few actual implementations to back up the theory. And the underlying theory has changed dramatically since 1975 based directly on experience with real and useful languages like C++ and Java.

    \Karl Banke\
    You soon end up with implementation rules like "No public method may ever be called from another public method if the same type of concern (whatever that is, but lets say authorization) is likely to be imposed on those methods. No concern may act on a method or class that is not public" This on the other hand leads to development of public methods as proxies for implementations for the sole purpose of being the target of a concern which in turn must be referred to as scattering......
    \Karl Banke\

    Nice, theoretical FUD of worst cases. You've never actually written any code using AOP, you don't know what a concern/pointcut/joinpoint/advice/aspect is, and yet you can predict where it's all going to lead. You can judge something without understanding it. That's amazing!!!!

    If you actually try using AOP and reject it based on your implementation experience, fine. But you're rejecting it based on nothing but predudices and vague conceptions and assertions.

        -Mike
  • \Karl Banke\

    > Mike, the funny thing is that there is no first class textbook on AOP.
    > \Karl Banke\
    >
    > Not being a deep comp sci person, lack of textbooks doesn't faze me very much (I doubt there's a "textbook" on perl but I find it quite usable). The existing books, particularly the newer ones that came out this year, are quite good IMHO.
    >

    Mike, I should disagree here. AOP is not another computer language, it is a new paradigm, a new way of thinking and designing systems. And if this new paradigm is not fully studied and all its pros, cons and structure details fully known and described, then the chance of it becoming the "next wave", or even a complimentary tecnique to be used with OOP, are much lower. There must be a first class book for this kind of paradigm change, or else the focus is lost, and it will be much harder to apply it on everyday's work.

    > \Karl Banke\
    > I have read a couple of books on AspectJ and they even fail to give a clear and abstract definition on what are pointcuts, an aspects, concerns, join points, advices and how they relate. This is *very* unlike where OOP was conceptually say 1975.
    > \Karl Banke\
    >
    > I responded to this in another thread - what I thought the definitions of the above were - and you never followed up.
    >
    > Pointcuts, jointpoints, and advices are extremely well defined, and I've yet to meet a person who _really_ read an AspectJ book not understand what they mean.
    >
    > "Aspects" and "Concerns" are more difficult. An aspect is as loosey-goosey in its definition as a Class is in OO - it's mostly just for defining your boundaries. A concern is pretty much entirely an abstract concept - just like you don't see "requirements" in code, just an implementation which reflects those requirements.
    >
    Ok, but this is not clear anywhere else. And who garantees me that what you say is really the final definition for these concepts? There must be others with a different view of these same concepts, and that's why a first class book, written by recognized people in the field, should exist: so that everyone comes down to the same knowledge, and build up from this common and strong foundation.

    > As for "where OO was conceptually say in 1975" - I hope you're joking. OO was very, very badly understood in 1975 with very, very few actual implementations to back up the theory. And the underlying theory has changed dramatically since 1975 based directly on experience with real and useful languages like C++ and Java.
    >
    Sorry to disagree. OO theory didn't change fundamentally, the base concepts were always there: Objects, Classes, Abstraction, Inheritance, Polymorphism. Simula already had most of these concepts in it, back in '67. The rest is implementation details.

    > If you actually try using AOP and reject it based on your implementation experience, fine. But you're rejecting it based on nothing but predudices and vague conceptions and assertions.

    Fully agree here.
  • \Henrique Steckelberg\
    Mike, I should disagree here. AOP is not another computer language, it is a new paradigm, a new way of thinking and designing systems. And if this new paradigm is not fully studied and all its pros, cons and structure details fully known and described, then the chance of it becoming the "next wave", or even a complimentary tecnique to be used with OOP, are much lower. There must be a first class book for this kind of paradigm change, or else the focus is lost, and it will be much harder to apply it on everyday's work.
    \Henrique Steckelberg\

    OO wasn't fully studied when C++ hit the scene, and it wasn't fully studied when Java hit the scene - in fact, you can hardly call it fully studied now.

    The point being that after awhile you have to stop studying and describing and start actually trying it in real situations. I think we're at that point with AOP.

    As for chances (and books playing a part) - books always follow practictioners, not vice versa. C++ didn't catch on so much as from books, as from the fact that it was OO, but you could still keep 99% of your code C and ease into it. Java adoption by comparison was exceptionally painful because it was a clean break with no compatability path.

    AspectJ allows you to ease into AOP w/out abandoning your Java code base. That will do far more for adoption than anything else. Perhaps down the road there will be another clean break and painful migration path, but for now I find AspectJ good enough to use in a commercial environment. In fact it's far easier to try out and learn AspectJ then it ever was for a C programmer to learn C++. The concepts between Java and AspectJ are much closer.

     \Henrique Steckelberg\
    Ok, but this is not clear anywhere else. And who garantees me that what you say is really the final definition for these concepts? There must be others with a different view of these same concepts, and that's why a first class book, written by recognized people in the field, should exist: so that everyone comes down to the same knowledge, and build up from this common and strong foundation.
    \Henrique Steckelberg\

    To this day people don't agree on what really makes a "class". Perhaps within the Java world they do, but not in the larger world. And in practice, use of OO varies wildly between C++, Java, Smalltalk, Perl, and a plethora of other languages. If you want safety in common definitions, I'm afraid you're not going to find it anywhere these days. Indeed, someone with a bulletproof academic OO background and extensive Java experience is going to find themselves in a world of hurt if they're asked to code in C++. Whether people like it or not, the language and implementation heavily skews OO in particular directions on a per language basis. The same is seen in AOP. In either case, you can make assertions on broad concepts, but they break down rather rapidly in the fact of actually coding them in a real language.

    In programming, subtlety matters. Take something as simple as the Singleton. Seems clean conceptually, right? Now try doing a Singleton in a J2EE app server with multiple class loaders. You find that the common ground isn't so common, and that there's very significant divergence in what OO means across various languages - and that lessons learned in one language "about OO" may have no applicability at all in another one.

    Another example - many C++ developers's routinely create solutions using multiple inheritance of implemenation, and this shapes their notion of OO. In plain old Java, they cannot do this, and the developers often go into a mini-state of shock. Both languages are "OO", but as it turns out that doesn't mean very much.

    In the end, I don't think AspectJ is the final destination of AOP, or that we're finished defining what AOP is (or even that AspectJ is finished evolving). But you seem to be suffering from believing that we're done defining OO, or in introducing OO languages. We're not. AOP and AspectJ are certainly in the early stages of creation, but that doesn't invalidate them. And to bring things full circle - I believe Java w/ AspectJ is a much more productive combination over all than plain Java. Really good books on the combination may help clarify this fact, but won't change the reality of what you can actually do. The capabilities are here, now, today.
     
         -Mike
  • Non-system-level AOP usecases[ Go to top ]

    <Mike>
    Not being a deep comp sci person, lack of textbooks doesn't faze me very much (I doubt there's a "textbook" on perl but I find it quite usable). The existing books, particularly the newer ones that came out this year, are quite good IMHO.
    </Mike>

    I would say that there are extremely well written books about perl. That is not my concern. Perl is a language, not a principle. There are good books about AspectJ (as I mentioned below) as well. I would very much like one of these become a common starting point to define what AOP is conceptually rather than technically.


    <Mike>
    "Aspects" and "Concerns" are more difficult. An aspect is as loosey-goosey in its definition as a Class is in OO - it's mostly just for defining your boundaries. A concern is pretty much entirely an abstract concept - just like you don't see "requirements" in code, just an implementation which reflects those requirements.
    </Mike>

    I would argue that as a least common denominator, an object is an entity that is comprised of data and operations on that data. I would say that this was even common consensus around 1975 (see below) and I still think it is a very crisp definition. No polymorphism, inheritance, classes, message passing definition etc. needed at that point. I can see that for advices and join points. I could do with "an arbitrary point in the program flow that can somehow be identified" and "an operation that is executed instead of join point". That is of course far better than what I could write down for an aspect :-(.

    Then again, one could argue that an aspect has nothing to do with aspect oriented programming per se and that is it just of value within an OO environment ;-). AOP would than just be "advice oriented programming" with the aspect just as one of the possible grouping entities. Also, I don't see static crosscutting there, but I have the feeling that it is inherently so different from "dynamic AOP" (not run time AOP) that it deserves to stand out as a different concept, if any.
     
    <Mike>
    As for "where OO was conceptually say in 1975" - I hope you're joking. OO was very, very badly understood in 1975 with very, very few actual implementations to back up the theory. And the underlying theory has changed dramatically since 1975 based directly on experience with real and useful languages like C++ and Java.
    </Mike>

    Well Mike, among other stuff Smalltalk-76 was just around the corner then and Smalltalk-80 - in many ways where our basic OO ideas come from - was not that far away. Conceptually, the idea of an object then was not that far from what it is now - but I fully understand one might argue differently.

    <Mike>
    Nice, theoretical FUD of worst cases. You've never actually written any code using AOP, you don't know what a concern/pointcut/joinpoint/advice/aspect is, and yet you can predict where it's all going to lead. You can judge something without understanding it. That's amazing!!!!
    </Mike>

    I know prefectly well what they are (in the Aspect/J fashion at least). What I describe is not a theoretical worst case. It is what happens in one of the easiest cross cutting business like cases imaginable - authorization. It also does not serve to show that AOP is evil but that - even in the simplest of (so called) business cases - you need full white box awareness of what the code is doing internally. If you manage without you either deliberately engineer around it which takes resources as well or you're just plain lucky. I am also quite sure that the same goes for so called system level cases but people reject to admit it - consider advices opening and committing(!) transactions without any notion about what they do internally. How do you prevent a "premature" commit in a basic plain localized program without any indirection hooks (like the server skeletons you may have within an application server environment) without knowing what the code actually does?.
     
    > If you actually try using AOP and reject it based on your implementation
    > experience, fine. But you're rejecting it based on nothing but predudices and > vague conceptions and assertions.

    As I said, I used it. I also think it can be a very powerful tool. Much the same way CLISP is a very powerful language.
  • Non-system-level AOP usecases[ Go to top ]

    Karl, try developing in Smalltalk for awhile, then developing in Java, then developing in C++, and tell me how OO gives you a solid background that helps you deal with each in turn (and presumably how OO helps you use the same concepts across languages).

    In fact - OO doesn't do that. You'll find the entire design of a Smalltalk application is radically different from C++ one, and again from a Java one - despite what OO says. Indeed, Smalltalk classes are mutable outside of the class code itself (classes, not objects). Message sending is not the same as method invocation. A classloader based byte-code system is not the same as a linked C++ app.

    Smalltalk didn't effectively die because it wasn't OO - it died because it was too slow for the time, and differed radically in syntax (and semantics!). C++ didn't take off because it was OO - in many ways it took off in the ways it shredded OO in the name of speed. And many of the pure OO concepts that C++ did pull in, such as diamond virtual multiple inheritance - have proven that OO concepts aren't always so hot in actual use.

    AOP has a solid theoretical base. It has several implementations, of which I believe AspectJ is the most solid. The leading Java-oriented Aspect systems do not require a blind leap into something new, but allow you ease into it at your own pace without sacrificing old code. Despite your comments, the basics are well understood. In fuzzier areas - what is a concern, what is an aspect - the "fuzziness" is no fuzzier than you see in the OO world when you look across multiple languages, or you peak in people's implementation code.

        -Mike
  • Non-system-level AOP usecases[ Go to top ]

    <Mike>
    Karl, try developing in Smalltalk for awhile, then developing in Java, then developing in C++, and tell me how OO gives you a solid background that helps you deal with each in turn (and presumably how OO helps you use the same concepts across languages).
    </Mike>

    This is an interesting question. And I do not agree with "OO doesn't do that". In fact I think that building applications in these different languages gives some interesting insights in what is sort of "at the core of OO" rather than what is "at the core of Smalltalk". Of course they still differ tremendously and of course I sort of grew a bit narrow minded by mostly working Java the last couple of years.

    <Mike>
    Smalltalk didn't effectively die because it wasn't OO - it died because it was too slow for the time, and differed radically in syntax (and semantics!). C++ didn't take off because it was OO - in many ways it took off in the ways it > shredded OO in the name of speed. And many of the pure OO concepts that C++ did pull in, such as diamond virtual multiple inheritance - have proven that OO concepts aren't always so hot in actual use.
    </Mike>

    From what I recall Smalltalk grinded to halt as Java emerged rather than C++, at least in some industries. I find this interesting because they turned to Smalltalk because they realized - long before Java was there - that C++ was not what they wanted loose in their companies. Anyway, I agree that Smalltalk had some syntactical and semantical elements that make for a bit of a shallow learning curve - and strange enough mostly for rather trivial control structures. The OO stuff was - and still is - beautiful, but maybe people can't do without private/public/protected/default/friend etc :-)

    <Mike>
    AOP has a solid theoretical base. It has several implementations, of which I believe AspectJ is the most solid. The leading Java-oriented Aspect systems do not require a blind leap into something new, but allow you ease into it at your own pace without sacrificing old code. Despite your comments, the basics are well understood. In fuzzier areas - what is a concern, what is an aspect - the "fuzziness" is no fuzzier than you see in the OO world when you look across multiple languages, or you peak in people's implementation code.
    </Mike>

    But now back to AOP. As I said, I still think that OO has some fundamental concepts that are valid across OO languages. Now for AOP the question is what are those concepts (not the artifacts). I sort of like the Aspect/J way, so I might say it is join/point, advice (pointcut considered syntactical sugar :-)) and aspect - leaving out static cross cutting for the time being. But is it really? Is "join point" then not equal to "hook" and "advice" equal to "interceptor"? Is "context" a mandatory or an optional element to consider a programming system "aspect oriented". Or should one take a step back and define AOP as a true extension of Object Orientation, with Aspects being first class Classes, Advices being Methods and vice versa. I would very much like such an approach because it would provide the closure of applying an advice on an aspect something that I sort of would anticipate to have in such an environment.....
  • Non-system-level AOP usecases[ Go to top ]

    \Karl Banke\
    This is an interesting question. And I do not agree with "OO doesn't do that". In fact I think that building applications in these different languages gives some interesting insights in what is sort of "at the core of OO" rather than what is "at the core of Smalltalk". Of course they still differ tremendously and of course I sort of grew a bit narrow minded by mostly working Java the last couple of years.
    \Karl Banke\

    Strictly talking from my own experience, "pure" OO theory seems to have been good for researching new languages, but very poor for applying it in day to day work. The solid kernel of OO which is inviolate across major OO languages that it's just not very useful. In less lofty terms, designs targted at semantics C++ tend to suck in any other language, designs for Java tend to suck in any other language....you get the idea.

    This is probably why I've had such problems with generalized OO modelling tools.

    \Karl Banke\
    From what I recall Smalltalk grinded to halt as Java emerged rather than C++, at least in some industries. I find this interesting because they turned to Smalltalk because they realized - long before Java was there - that C++ was not what they wanted loose in their companies. Anyway, I agree that Smalltalk had some syntactical and semantical elements that make for a bit of a shallow learning curve - and strange enough mostly for rather trivial control structures. The OO stuff was - and still is - beautiful, but maybe people can't do without private/public/protected/default/friend etc :-)
    \Karl Banke\

    In the "early years", the big problem was always runtime speed. The violently non-procedural semantics and syntax just made it harder to swallow, particularly later on when speed became less of an issue. In fact, Smalltalk seemed to be dying to me when Java came along, and then sprang back with a resurrgence. Once people saw what you could do with Java, it validated much of Smalltalk after the fact.

    What finally put the nail in the coffin, IMHO, was lack of standardization. Oh, there was a some, but Smalltalk code as a rule was tightly tied to one implementation, and third-party Smalltalk "libraries" which could be used on multiple Smalltalk implementations were few and far between. Compared to Java, where a .jar is a .jar is a .jar, this was a heavy blow, and app servers only made this difference more apparent.

    \Karl Banke\
    But now back to AOP. As I said, I still think that OO has some fundamental concepts that are valid across OO languages. Now for AOP the question is what are those concepts (not the artifacts). I sort of like the Aspect/J way, so I might say it is join/point, advice (pointcut considered syntactical sugar :-)) and aspect - leaving out static cross cutting for the time being. But is it really? Is "join point" then not equal to "hook" and "advice" equal to "interceptor"? Is "context" a mandatory or an optional element to consider a programming system "aspect oriented". Or should one take a step back and define AOP as a true extension of Object Orientation, with Aspects being first class Classes, Advices being Methods and vice versa. I would very much like such an approach because it would provide the closure of applying an advice on an aspect something that I sort of would anticipate to have in such an environment.....
    \Karl Banke\

    Ah, now that's a worthwhile discussion. In many ways AspectJ is a compromise, and for people like me it's valuable for it to be "in addition to" Java. They achieve alot with additional language elements tacked on, with little/no fiddling with base Java, and get a fair degree of modularization and safety. Things like Aspects and pointcuts aren't quite first class, but also not second class - they live in a bit of a shadow world between the two.

    I agree that a really first-class integration of aspects into a language would give you more control and have other desirable characteristics, and in such a world "joinpoint/pointcut/advice" might be treated differently (and with different terminology). But this is no different from the OO world. Lots of classic OO textbooks insist on talking about "message sends", and confuse the hell out of Java/C++ people who deal with method invokes on objects, not sending messages to them. Just like method invocation, as a terminology, might not make a Smalltalker real happy.

    When there's this kind of disconnect, it mostly shows that abstract concepts and theory only take you a limited way into a problem space, and aren't very useful with concrete implementations (and those implementations can contradict each other and the generalized theory).

    For me and for right now, AspectJ and its joinpoints/pointcuts/advice et al are good enough. And I fully expect AspectJ to grow (such as recent discussions on making pointcuts more extensible). At the same time, this is obviously only one route, which is attractive to people like me because its so Java compatible. This compatability is crucial to get into organizations slowly. At some future stage, someone might create a more integrated language where Aspect features and OO live 100% side by side, but that's going to be a much bigger jump and much harder fight (just like it was when Java was introduced). So something like AspectJ may be just an intermediate step - but history shows that intermediate steps are often crucial bridges from the past into new areas.

        -Mike
  • Well said![ Go to top ]

    Nice post, Mike. Very pragmatic.

    -Ramnivas
  • AOP, is it sane?[ Go to top ]

    So I define a 'thing to do', and then define where I want the thing to be done, somewhere other than where it will be done. Hmmmmm. This will not improve understandability of code. Unless it is just a preprocessing activity.

    Of course an IDE can decorate the text to correct this deficiency, but this appears to reinforce the weakness.

    I love it as a debugging/prototyping tool. I can also see it as useful in a metaprogramming environment. I do not, however, think it should become part of the language. That implies that the 'real' text is hidden, and hiding is bad.
  • AOP, is it sane?[ Go to top ]

    \Richard Henderson\
    I love it as a debugging/prototyping tool. I can also see it as useful in a metaprogramming environment. I do not, however, think it should become part of the language. That implies that the 'real' text is hidden, and hiding is bad.
    \Richard Henderson\

    In a language like AspectJ, nothing is being hidden. Instead, behavior is re-arranged differently so that you get better functional modularity.

    A useful analogy in the OO world is basic inheritance. A single class' API or an interface definition doesn't completely define what a class can do - because someone can extend the class, or implement the interface. Specific behavior are isolated to where they make sense. You can find out concrete behavior of an abstract class or interface only by figuring out the concrete class behind it.

    AOP works like that, but using mechanisms other than inheritance to accomplish some of the same sort of goals (modularity, encapsulation).

    There is alot of power in the specific AOP mechanisms AspectJ implements, but the purpose of doing it at the language level is to held constrain that power, and to make it obvious that you're _programming_. AspectJ aspects/pointcuts/advice live as (almost) first class objects in your code - and that code is side-by-side to your normal Java code. Your aspects may be in seperate source files, or packages, but it's still code, and it's not hidden.

    This is in contrast to many of the non-language AOP systems out there. In those cases, AOP is controlled via configuration (possibly pointing to Aspect-aware Java code). There, you feel a disconnect - there's writing code, and then there's a seperate "configuring the aspects" part. And the aspect part (again, possibly Java code) is forced to do alot of casts because most pieces of the target Java code is only exposed as Object.

    So I see it as two broad approaches - one in which AOP is exposed as a language-level tool in the OO developers tool box, and where its obvious you're still writing code and its under your control, and you have all the normal power and abstraction mechanisms available under Java. And then there's another where AOP isn't a language at all, it's a runtime system which is configured externally (or someday maybe by meta-data in classes), and which doesn't feel so much like coding as setting up a configuration for someone.

        -Mike
  • AOP, is it sane?[ Go to top ]

    If I cannot tell what is happening at some point in the code, by looking at that point in the code, then the behaviour is hidden.

    If the point of action is defined by an abstract pattern, then one is entirely reliant on a tool to expose these transformation points.

    I bet debugging can be really nasty.
  • AOP, is it sane?[ Go to top ]

    If I cannot tell what is happening at some point in the code, by looking at that point in the code, then the behaviour is hidden. ... I bet debugging can be really nasty.

    This was perhaps the biggest complaint about Delphi, which had a mechanism similar to aspects for invisibly attaching external logic to the business routines. I read that debugging was a nightmare. Where is Delphi now?
  • AOP as part of MDA[ Go to top ]

    Hello,

    reading articles about AOP and MDA as well I think that the goal of AOP to interweave several structures (or aspects) can be accomplished nicely by use of the MDA methodology.

    MDA introduces the concept of a layered stack of obect oriented modells. The top level modell is refered to as the PIM. The subsequent modell is refered to as the PSM and can be generated by usage of transformation tools.

    In my understanding the tranformation process between the distinct modells could serve as a means to interweave distinct aspects as they are present in the AOP world as well.

    In the case of the given example the drawing aspect could be taken into account by introduction of an abstract stereotype Displayable which would be assigned to the concerned methods (setX(), setY(), setP1(), setP2())

    Another posibility would be to modell the affiliation to a specific aspect by introducing a special type DisplayAspect. Every Class which has got something to do with that aspect would inherit from that type. The transformation mechanism from PIM to PSM once again would be responsible for the actual interweaving.

    Seems like AOP at least can be seen as part of OOD ;-)

    Kindest Regards,


    A. Thomas