Slashdot Mirror


Aspect-Oriented Programming with AspectJ

Verity Stob writes "There is a turning point in the emergence of a programming methodology. It doesn't matter how big and popular the website is, nor how many papers have been published in the ACM journals or development magazines, nor even whether the first conferences have been a sell-out. A methodology hasn't made really made it until somebody has published a Proper Book. With Aspect-Oriented Programming with AspectJ author Ivan Kiselev is bidding to drag AOP into the mainstream. He is motivated, he says in his introduction, by the recollection of the 25 odd years it took for the object-oriented concept to spread from its Simula origins in frosty Norway to being the everyday tool of Joe Coder. He aims to prevent this delay happening to AOP." Read on for Verity Stob's review of Kiselev's book. Aspect-Oriented Programming with AspectJ author Ivan Kiselev pages 274 publisher SAMS rating Excellent reviewer Verity Stob ISBN 0672324105 summary Introduction to a new programming technique using an extension to Java

He has divided the book into four parts. Part I provides a brief sketch of AOP and introduces its concepts. AOP builds on OOP, asserting that we need a new programming entity called, wait for it, an aspect. Mr Kiselev's explanation of aspects reminded me of that bit in The Hitchhiker's Guide to the Galaxy when the planet Golgafrincham divided its population into A types (who were the leaders, the scientists and the great artists), the C types (who were the people who did all the actual making of things and doing of things), and the B types, who comprised everybody left over: telephone sanitizers, advertising account executives and hairdressers. As I understand Mr Kiselev, the AOP view of things is that objects and classes (A type thinkers) and low-level procedures and APIs (C type doers) can be nicely encapsulated using traditional components. But aspects, software's little hairdressers, get their fingers into everything, and until now there has been no way to encapsulate them. This of course is what AOP in general and specifically the AspectJ superset of the Java language set out to do.

AspectJ's eponymous aspects are constructs not unlike ordinary classes. Mr Kiselev has not resisted the temptation to make an aspect Hello World example, and it looks reassuringly so-whatish:

package intro;

import java.io.*;

public aspect HelloWorldA
{
public static void main(String args[])
{
System.out.println(Hello, world!);
}
}

Mr Kiselev then lays out his stall of New Things. A join point is any point in execution flow that AspectJ can identify and -- to get slightly ahead of ourselves -- execute some extra code. The most frequently used kind of join point being the call to a method. Pointcuts specify collections of join points; as a regular expression is to an instance of matched text, so a pointcut is to a matching join point. An advice (with horrid plural 'advices') is the code to be executed when a given pointcut is matched. If you are familiar with Eiffel's pre- and post-conditions, then you'll understand if I say that it is common for advices to run in the same way, topping and/or tailing the execution of a method. The differences are that aspects are specified from outside the method without touching the method or its class's code, and that aspects can be applied to multiple methods in one go. Mr Kiselev concludes this section of the book with a few simplistic examples of 'here is class A, here is class B' kind.

In Part II Mr Kiselev rolls up his sleeves and takes us through an extended, realistic example. I did wonder if perhaps it weren't a wee bit too realistic, as it is a miniature website application for news story submission and reading -- sort of Slashdot Ultralite -- all done using JSP and a MySQL database. Just explaining this setup, without even using any AspectJ, consumes a 15-page chapter. Since I am a C++ programmer who has not had any contact with JSP, I was initially anxious that I might not be able to follow this. However, recalling that www.[name withheld].com, the clumsiest, ugliest corporate website on the Internet, is programmed in JSP, I reasoned that if the dolts that programmed that site could understand JSP then it couldn't be very hard. So it proved.

The first example comprises adding password protection to the application. This is achieved by adding an advice that intercepts calls to doStartTag() methods. The advice can test if the user is logged in and, if he isn't, throw an exception that will dump him back at the login page. (Who says exceptions aren't 21st century gotos?) At this point Mr Kiselev admits that the cute 10-line implementation that he initially shows is in reality a non-starter; for one thing not all pages that must be secured define doStartTag() methods, for another the aspect can't reach an instance variable it needs to read because it is declared in protected scope. The second problem is easily overcome. AOP offers a mechanism by which extra classes can be bodged ('introduced' is the preferred verb in the AOP community) into the hierarchy as parents of existing classes. He uses this to add an accessor method for the field in question. The other problem is not so neatly smothered, and it is somewhat ruefully that Mr Kiselev produces his final, two-page solution. But I think that it is greatly to Mr K's credit that he does this - it tastes like programming in the real world as I have experienced it.

For the rest of Part II, Mr K demonstrates other applications of AOP using the AspectNews code. This includes Eiffelish design-by-contract stuff, improved exception handling, various debugging and tuning techniques (specifically logging, tracing and profiling) and a chapter on runtime improvements - stream buffering, database connection pooling and result caching - which show the AOP way to do things, usually where I would expect to be putting in proxy classes.

In part III we get down and dirty with the AspectJ language. This is the part where the book explains the obscure stuff: how to make a pointcut that picks up object preinitialization, or make an advice that goes off only when you are exiting a method on the back of an exception. I skimmed this bit - I guess it will become vital when I start using AspectJ in earnest. It looked good and clear on a flick through. A brief part IV contains some patterns, to give one a start when engaging AspectJ in earnest. Apparently it is horribly easy to create infinitely recursive situations, so if you here a faint popping sound from your machine it will be the stack colliding with the heap. There are seven appendices, supplying such things as a summary of the API in AspectJ's packages and hints on obtaining and using the Open Source supplementary tools mentioned in the book (Tomcat JSP container, MySQL database and Ant make replacement). AspectJ itself, now escaped from Xerox PARC, can be downloaded from the Eclipse website.

Complaints? None really. Oh all right, here's a nitpicklette because it's you: at page 75 Mr Kiselev adopts the irritating Internet habit of writing 'loosing' when he means 'losing'. Note to publisher SAMS proofreaders: do I win 25 cents?

For the rest, this is a lucid and readable book that describes the Next Big Methodology. I'm a bit alarmed at the prospect of squeezing new actions into the cracks of existing code, but I dare say I'll grow to love it.

A word of warning to the eager: since this technology is currently implemented as a species of preprocessor that relies on having all the source code available at once, so it is rather slow and probably isn't going into production shops for a while. There again, I seem to remember the comparable Cfront C++ compiler doing rather well, before we had platform-native C++ compilers.

And to the sceptics: if you think you can ignore AOP, don't forget the fate of the A and C type inhabitants of Golgafrincham, who having sent their B type telephone sanitizers into exile were all wiped out by a germ caught from a particularly dirty telephone.

You can purchase Aspect-Oriented Programming with AspectJ from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

25 of 426 comments (clear)

  1. Re:Where's this useful? by Mahrin+Skel · · Score: 4, Informative
    I can see it. Okay, you know how OOP lets you over-ride ancestor behaviour in descendants? But if you want to combine the behaviour of two different objects you have to either encapsulate one in the other, or go all the way back to their common ancestor and create a new descendent line because if you change the root line then *all* descendants are changed?

    AOP would seem to let you over-ride methods or invoke special handling *without* touching the object directly. You simply tell the compiler "When this method is called, do this first (or afterwards)."

    On the one hand, this could lead to spagetti code nightmares, since execution paths could become effectively untraceable. On the other, it's in many ways cleaner than putting your special-case or over-ride code directly into the methods and objects directly.

    --Dave

  2. Re:Where's this useful? by cushty · · Score: 5, Informative

    Aspects are cross-cutting concerns, they are things that cut through numbers of classes. My way of thinking: draw vertical rectangles side-by-side and call these "classes", now draw a horizontal box that cuts through them all and this is an "aspect".

    The simple example, and one used in the book I believe, is that of logging. Say you have to log the entry to and exit from every single method in your code. Typically you would probably write this directly putting "entering XYZ, exitting XYZ" actually in the code. But with aspects you can write one aspect that basically says "on entry to any method log the method and parameters, on exit log the method" and compile your code and away you go.

    So? Why would I want to do this? Well, now that you have been through your development process and discovered everything runs fine, you decide to go into production. Want to remove every single log line to improve speed? With the "normal" approach you'll have to write a script to remove them or do it manually. With aspects: just dont use the aspect in the compilation! Put them back in by compiling in the aspect again.

    For me aspects are a real benefit but they do you head in for a while when you're an OO programmer!

  3. Re:What is Aspect Oriented? by DamnStupidElf · · Score: 2, Informative

    It looks like the concept is to group common methods from many different classes into a form that can be acted on uniformly. The example they gave allows for the creation of several multi-layer classes, all related and built upon each other. A "join point" is constructed as a collection of all methods that actually create new objects. The article explained that this is particularly useful for security, since while there may be many different classes that can be created, a join point can be used to allow or disallow the creation of any or all of them in a single place. The advantage is that security code does not have to be maintained in each class independantly.

  4. Re:Yet another reason to switch to Lisp by swagr · · Score: 3, Informative

    Take advantage of both languages.
    Of course, as everyone knows, there are Scheme/Lisp implementetions in Java:
    http://grunge.cs.tu-berlin.de/~tolk/vmlangu ages.ht ml
    Ones that act as interpreters or compilers to Java byte code.
    Or write your own (it's not that hard) http://www.paulgraham.com/rootsoflisp.html

    --

    -... --- .-. . -.. ..--..
  5. Other Aspect Oriented Technologies by Frums · · Score: 4, Informative

    Since AspectJ is getting some attention I figured i would point out some other AOP resources

    • MDSOC - Paper - Is basically IBM's take on AOP. It avoids creating Aspect Space and Object Space (what belongs in an aspect, what in an Object?) but is less mature than AspectJ
    • HyperJ - Home - IBM's Java language stuff supporting MDSOC
    • JAC - Home - Aspect oriented middleware for Java. I haven;t explored this one much, is on my todo list.
    • Aspect Browser - Home- A tool to help identify crosscutting concerns in Java (emacs!)
  6. Workarounds? by mparaz · · Score: 4, Informative
  7. Re:Where's this useful? by Enonu · · Score: 5, Informative

    Yeah, this review didn't introduce AOP that well.

    Going here:
    http://dev.eclipse.org/viewcvs/indextech.cg i/~checkout~/aspectj-home/doc/progguide/index.html

    I found this code example:

    pointcut move(): call(void FigureElement.setXY(int,int)) ||
    call(void Point.setX(int)) ||
    call(void Point.setY(int)) ||
    call(void Line.setP1(Point)) ||
    call(void Line.setP2(Point));

    and then this:

    after(): move() {
    System.out.println("A figure element moved.");
    }

    As you can see, "after" any method call as defined by the pointcut, System.out.println is executed to reflect this fact.

    I can see how this would be great for logging, checking pre/post conditions, quicker debugging, or anything else that is of a "horizontal" nature in your code.

  8. Re:So, what is it? by Halo1 · · Score: 2, Informative

    The original article that introduced it can be found here (download links for the article in several formats are at the top). Google also has a nice collection of links.

    --
    Donate free food here
  9. Re:So, what is this? by whazzy · · Score: 3, Informative

    Aspect-oriented programming (AOP) is a new language paradigm proposed for cleanly modularizing the crosscutting structure of concerns such as exception handling, synchronization, performance optimizations, and r esource sharing,that are usually difficult to express cleanly in source code using existing programming techniques. AOP can control such code tangling and make the underlying concerns more apparent, making programs easier to develop and maintain. In aspect-oriented programs, the basic program unit is an aspect. An aspect with its encapsulation of state with associated advice, introductions, and methods (operations) is a significantly different abstraction in comparison to the procedure units within procedural programs or class units within object-oriented programs. The inclusion of join points in an aspect further complicates the static and dynamic relations between aspects and classes My humble request:Please take a moment to use Google before you feel the urge to click the submit button here:-)\

  10. Re:Where's this useful? by ndvaughan · · Score: 2, Informative

    I did a paper on AOP last semester. Basically, AOP not only gives you an object-oriented view of the code, but also splits it up according to other aspects of its functionality, like "security", or "debugging". Then, when you want to add a certain functionality to multiple objects, all you do is name all of the class methods that are affected (called a "joinpoint"), and then write one section of code, instead of changing each and every object (or class) that you would have to do if you were using an OO language. Go to http://www.parc.com/groups/csl/projects/aspectj/in dex.html and look at some of the PPT presentations. They describe it pretty well.

  11. Re:What is Aspect Oriented? by WeaponOfChoice · · Score: 2, Informative

    The advantage is that security code does not have to be maintained in each class independantly

    This is precisely what I use AOP for. Whilst there is tremendous opportunity for spaghetti coding, so long as you adhere to some reasonable standard of layout and documentation it works out much more maintainable for certain design patterns.

    --


    It's not that I'm Anti-American - I'm Pro-Freedom
  12. AOP Resources by Vagary · · Score: 3, Informative

    The Software Practices Lab at UBC has been doing all sorts of AOP research lately. Of particular interest:

    • A study to determine whether AOP is actually useful.
    • Implementation of all the GoF Design Patterns in both vanilla Java and AspectJ.

    They're also working on AspectC and AspectSmalltalk. It's my understanding that UBC is one of the major world centers in AOP research -- do you think I should do a PhD there?

  13. Re:Where's this useful? by MsWillow · · Score: 4, Informative

    Want to remove every single log line to improve speed? With the "normal" approach you'll have to write a script to remove them or do it manually.

    Or you change one #define in one .h file, re-compile and you're golden. That removes all the #ifdef debug code you put in when you were writing it.

    Do they teach programmers anything useful these days? Sheesh.

    --

    Lemon curry?
  14. AspectJ is a safe warm power drill by Anonymous Coward · · Score: 3, Informative

    I'd have to disagree that it won't be used in production shops any time soon. It's really a matter of the word getting out, which undoubtedly will be helped by both the book and the appearance of this review on /.

    A team I was on early last year had a legacy Java db access module that was rife with poor exception handling. We wrote a single aspect that joined on all exceptions, trapping only JDBC exceptions, and had the aspect trap the SQL error code, the ISAM error code, the offending method and source code line. After recompiling the module with the aspect included, we popped the new JAR into production and used the trace files to find the offending code. Altogether it took 2 days to address the errors. So we re-recompiled the JAR, this time with the aspect removed, into production it went, and received a few beers for our "inventiveness."

    Honestly, this is one of the most useful Java tools I've ever run across. I guess I should have sent the PARC guys money for some tallboys.

  15. Re:My 2 bits... by ctrimble · · Score: 3, Informative

    Gregor Kiczales, the lead on the AspectJ project, wrote "The Art of the Metaobject Protocol", which was a description of how to do metaobjects in Lisp (metaobjects, and particularly generic functions, are closely related to AOP). A description that Gabriel and Steele put together can be found in The Common Lisp Object System: An Overview

  16. Verity Stob by Dylan2000 · · Score: 3, Informative

    is not really a real person but is one of the funniest tech writers out there. She is famous for the history of the microcomputer, and is widely and deeply revered by everybody who's read her

    She also did a parody of our own Slashdot, which is absolutely f*cking hilarious.

    I strongly recommend anyone who hasn't read any stob to go and check out the archives and then laugh yourself stupid for half an hour.

    --
    Build your own website - full service homepage system your m
  17. Re:Where's this useful? by Anonymous Coward · · Score: 1, Informative
    It sounds to me like the main selling points of AOP are that you don't have to design things well in the first place, because if you missed something, well then you can change how your objects behave without redesigning them.


    No, that isn't the purpose of AOP, although it can seem like that when you get the newsbite version of it. The goal of AOP isn't so you can string in extra code you forgot, it's so you can cleanly separate the different parts (aspects) of your program so that someone can see the real purpose of a method/class/package without seeing all the extra cruft that is needed but is incidental to the main purpose (error handling, logging, persistence, etc).

    The typical example is in adding logging behaviour to a system. AOP isn't there so much so that you can say "Oh yeah, we need to log this stuff" after the fact (after all, in normal OOP the programmer can always just paste in the required code to all the methods). Rather it's identifying that the log code is entirely orthogonal to the main purpose of the system, and as such doesn't really "belong" in the method definitions. It has nothing to do with the real purpose of the method, the only reason it is there is because the only way to get the desired behaviour when that method is executed is (was) to actually drop all the logging code directly into the method.

    The biggest beef many people (myself included) have with AOP is the fact that it has the potential to make your programs completely unreadable or unmaintainable (but, then again, show me a programming paradigm where it's impossible to make unreadable/unmaintainable programs). This happens when people misunderstand the purpose of aspects, and start using them to do things they shouldn't be used for (namely, the reasons you mention above: to tack on extra code to a method, code that really is a proper part of the method, but was stuffed into an aspect because of inexperience/laziness/gee-whiz-aspects-are-great. IMHO, AOP is still so new that we don't really have a good set of idioms for what should be in an aspect and what should be in the method proper.

  18. Re:So, what is this? by Minna+Kirai · · Score: 2, Informative

    They certainly wouldn't approve of manually adding hooks everyplace, which is what AOP tries to avoid (while still giving the programmer the power as if that had been done)

    How far would AOP meet with his approval? Good enough, it seems. Dijkstra's criteria for allowing a feature into a language was how much it complicated the description of the "cursor position" ("textual index point") of a program at a certain time. Gotos are bad, because they make the size required to describe that position unbounded (the full history of all previous goto jumps). Structured programming, with nested blocks and function calls, keeps the size limited, because the position-descriptor shrinks when you leave a block. (As long as there's no infinite recursion, but even that can sometimes be handled)

    AOP's effect on the execution graph is the same as function calls. It's just the calling of functions, but the calls themselves are implicit and invisible. The textual index size is only increased by a small constant factor per aspect called, and that size is recovered when it's done.

  19. Re:Yet another reason to switch to Lisp by antifuchs · · Score: 2, Informative
    Some points about your posting:

    Either you have stuck around with too many bad lisp programmers, or you haven't paid enough attention to what they were doing - no usefulness can come from code which uses lists for anything more than they were designed for - sequences of data. (-:

    Also, it is not very rewarding to just clip the first element off the list you gave - it will still be around (not being garbage collected until the pointer to the head is), so why bother?

    Scheme is not, in any way I can think of, over-extended. It is designed to be a minimalistic language - hells, it even has minimalistic syntax. Please check your facts before you claim such things. Common Lisp does have a hell of a standard, though. But see Greenspun's tenth rule for why.

    And concerning your hate of paranthesis, I can only believe that you have mapped your () buttons to the wrong keys - using them from a non-shifted key (dump those []s, for example (-;) makes them much easier to type (and having an editor which can operate with the lists your code forms, helps too - use vi -l or emacs).

    --
    this post was brought to you by Andreas Fuchs.
    echo [Address] | sed s/[-a-z]//g | tr A-Z a-z
  20. Re:So, what is this? by cyclist1200 · · Score: 2, Informative

    I read about it about a year ago in Java Pro.

    Here's an article

    And here
    And here

    Hope that helps.

  21. AOP in C++ by thedigitalbean · · Score: 2, Informative

    For those of you who are C++ programers and would like to see Aspects in C++ check out:

    aspectc.org

    They are at revision 0.6 but they do provide many of the useful features in AOP. My one beef is that they don't provide the ability to specify aspects based on the 'const-ness' of a function, but hey its only 0.6 and they have a way to go before 1.0

  22. Why is the number 1 not an object? by Merk · · Score: 2, Informative

    In Ruby:
    1.times { puts "Hello World!" }

    Now there are other ways of doing that that are almost as readable and almost as useful but isn't that neat? What makes treating everything as an object even more useful is that you can treat everything the same way. You can always say obj.inspect and get something useful out of it. This is great when you're debugging something and wonder: "What the heck is this function returning?", whether it's an integer, a hash or a complex object, object.inspect will always work.

    Java makes things confusing by having both primitive types (int) and object types (Integer), because in some situations you want to be dealing with an object, but the language isn't flexible enough to let you treat the object form of an Integer the same way you would a primitive int.

    What I think makes Ruby so cool is that essentially everything in Ruby is, or can be an object, but it doesn't get in the way.

    I agree that languages that are inflexible can be rough because they limit your options, but how is treating everything like an object inflexible?

  23. Re:I prefer reading... by etcpasswd · · Score: 2, Informative
    Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged - the compiler knows the types anyway and can check those, and it only confuses the programmer. No wonder MicroSoft makes buggy programs.

    Variable names are for the programmer - not compiler. Also, weakly typed languages like C will compile the code with mismatching types. Hungarian notation is just a mechanical way to name your variables consistently. I don't think Code Complete insists on Hungarian; most of the book is about throwing more light on the issues than forcing you to follow a specific standard. It is a good beginner's book, IMO.

  24. Re:Yet another reason to switch to Lisp by Phs2501 · · Score: 2, Informative
    Any reasonably complex structured data will probably be put into a structure or class in Common Lisp. In addition to being specified, you get constant-time access to the elements:

    ;;;; Leading dots are because of slashcode lameness
    (defstruct item
    . "Strores a gronk foobar blazwart mrph."
    . quantity
    . product-code
    . name
    . description)

    (make-item :quantity 5
    . . . . . .:product-code 256
    . . . . . .:name "Item"
    . . . . . .:description "Description")
    Or you'd be putting data into a class, hash table, array, or whatever.

    Common Lisp is not just about lists.

  25. Here is what it is: by Rimbo · · Score: 2, Informative

    I had a chance to read about AOP a few years ago, when it was first being introduced.

    Short answer: Yes, it is the Next Big Thing.

    In the same sort of way that procedures were already implemented by experienced programmers long before languages like Pascal came to be,

    In the same sort of way that experienced programmers used virtual function lookup tables and information hiding before OOP came about,

    So is AOP. It is program-language-level support for the sorts of things experienced programmers do already... namely, code generation and automatic code modification.

    Basically the reason OOP came about was that there was no means to add functionality to code without going into that code and inserting a call to the new functionality. Experienced programmers made virtual functions and lookup tables to solve this issue, but obviously this sort of code is complex and prone to error. So OOP brought forth program-language-level support for this sort of feature.

    The problem that AOP addresses is this: As powerful as OOP is, it still relies on functional decomposition. The trouble is, sometimes one thing changes that cuts across functional boundaries. For example, the performance of an application, when ported to a new system, may need an entirely different set of performance tuning for the new app. Or more likely, you simply didn't see some aspect (there's that word) of your code changing often, and it would be impossible to separate it into a module without restructuring your entire code.

    Now you can do a lot of inline #ifdef's and the like to do this by hand. Or, you can use some sort of dynamic code generation. But writing a dynamic code generator by hand is, like the virtual function table example above, tricky and always ad hoc.

    The ultimate goal behind AOP is to make code generation generalized and done at the language level. So that you can modify things that occur across the boundaries of the existing functional decomposition.

    Does that make any sense?