By Ramnivas Laddad, author of AspectJ in Action, Second Edition
What is the real deal with AOP? Is it something that you should embrace or ignore? What do you gain with AOP, and what do you risk by adopting it? In this article, based on AspectJ in Action, Second Edition, the author provides the answers.
Let's address these important questions from a practitioner's point of view. We'll start with AOP in the context of the typical hype cycle. This will give us a historical perspective on AOP evolution and indicate what lies ahead. We also look at the landscape. While AOP is a more general concept, because our focus is the real world use of it, we'll focus on AspectJ—its most prominent implementation.
Every technology goes through a cycle that's well illustrated by the Gartner Hype Cycle (http://en.wikipedia.org/wiki/Hype_cycle). AOP is no exception. Understanding the hype cycle and the position of the technology you're considering adopting is important. It allows you to offer a more accurate gauge of the benefits the technology is likely to offer and the risk you expose yourself to. In this section, I'll give my assessment of the hype cycle of AOP in five major phases: technology trigger, peak of inflated expectations, trough of disillusionment, slope of enlightenment, and plateau of productivity. The following figure depicts the hype cycle and how AOP maps to it.
Figure 1 Hype cycle for AOP. After passing through various stages, currently AOP is on the slope of enlightenment. (Hype not to scale!)
Let's look at each of the major phases in the figure.
In this phase, a new technology appears on the horizon with a promise to solve a set of problems. It may be an announcement of a new product or an actual release of a product. Either way, it may generate some buzz and attract developers towards it.
For AOP, the technology trigger occurred with AspectJ 1.0 release in 2002 followed by a more serious 1.1 release in 2003 (earlier releases, although interesting, didn't receive much attention). Gregor Kiczales and his team, while working at Xerox Palo Alto Research Center (PARC), developed the AOP concepts backed by the AspectJ language. Many technologists could immediately understand the potential for AspectJ, especially for enterprise applications. Aspect-oriented programming using AspectJ was seen as a way to modularize some of the common crosscutting concerns—transaction management, security, caching, concurrency control, and lest we forget, tracing.
For many technologies, especially with substantially new ideas and potential to solve complex problems, the next phase follows.
In this phase, the technology gains much hype (warranted or otherwise). Everyone wants to know about it, everyone has an opinion of it, but few people use it in real applications. A few adventurous (or reckless) developers (or early adopters) try it. If the technology fits the problem well, and you have good understanding of it, adopting technology during this phase can give you a competitive advantage. It's fascinating to be associated with a technology in this phase. People perceive you as "cool."
For AOP, the peak occurred around 2004. I enjoyed the attention I received as well as the response to the first edition of AspectJ in Action (thank you!). Many smaller companies and a few larger ones used AspectJ in a few projects. During this time, most developers working on AspectJ and AspectJ Development Tools (AJDT) were from IBM. This significant investment from IBM helped AspectJ gain solid footing.
But the lack of mass adoption made using the technology an adventure. Fortunately for AspectJ the peak wasn't high due to expectation management by AspectJ evangelists. For example, Gregor Kiczales, the father of AOP, portrayed AspectJ as the "15% solution" (http://www.ddj.com/architect/184414845): he argues that in a typical project, you'll use AspectJ for about 15% of your coding. Think about it. When was the last time the creator of a language quoted such a small number for his own language? Nevertheless, we have to make progress—one step at a time." This expectation management led to a smaller peak in the hype cycle and, fortunately, a shorter fall in the next phase.
In this phase, the technology starts to lose the attention it once received. It becomes one of many things vying for attention. In this phase, many early adopters continue to use the technology creatively to gain a competitive advantage. Others begin to look at it with a skeptical eye. The technology sees serious and innovative competition from newer solutions that address part of the same problem space. Interestingly, many of these competing technologies are going through the "peak of inflated expectation" phase. On one extreme, these new technologies can drive the existing one into oblivion (which isn't necessarily a bad thing—if the technology couldn't take on a competition, oblivion is a respectful resting place). On the other side, competition can shake the technology and force it to innovate further.
For AOP, the trough occurred around 2006. In addition to the naturally expected trough that follows a peak, Java 5 also proved to be disruptive to implementing other features needed in making AspectJ an easily acceptable technology—compiler and weaver speed, tools integration, and so on. Although the core AJDT committers kept developing the technology, much more dedicated effort was needed. Furthermore, many users perceived the adoption of AspectJ as a big step due to the requirement of using a brand-new syntax and the need to use a special compiler at the beginning of a project. Eclipse, the main supported IDE for AspectJ, was advancing at a rapid pace, leaving a large gap between its Java support and AspectJ support.
Enterprise Java Beans (EJB) provided serious competition. Through a framework-centric approach, you could implement crosscutting functionality such as transaction management and security in a modular fashion. More serious competition came from dynamic languages such as Ruby and Groovy and associated frameworks such as Rails and Grails. The metaprogramming model available in these technologies provided an alternative solution to modularize crosscutting concerns.
On the tooling side, all new languages suffer from the lack of maturity (although most new language proponents would argue otherwise). In reality, tools always lag behind language creation. I still remember using Emacs with Java for several years after disappointing experiences with many IDEs. But this didn't cause us early Java adopters to discard the language for the lack of tools. A judicious decision requires that you weigh the benefits of the language against the handicaps introduced by immature or nonexisting tools. For AspectJ, the tools side—especially IDEs—has been a weakness, especially if you expected its support to match that of Java.
AspectJ took on all these challenges to enter the next—and most useful—phase.
This phase results from multiple factors such as changes in the technology to meet real-world requirements, maturing of the technology due to sustained field testing, finding the right context for the technology to make an impact, and disillusionment about other technologies once considered as alternatives. The technology also starts to be used to solve problems in the context of focused application areas.
The slope of enlightenment started for AOP right after its trough. Adrian Colyer, the AspectJ lead, left IBM to join SpringSource. Soon, I joined SpringSource, and I've been contributing to Spring AspectJ integration as a committer. Later, Andy Clement, a lead AspectJ developer, also left IBM to join SpringSource. Recently, Andrew Eisenberg joined SpringSource and is working on improving AspectJ-related tools. Currently, AspectJ is a SpringSource portfolio project and enjoys its sponsorship. All these factors helped bring together Spring and AspectJ and afford sustained development.
During my consulting engagements, I see signs of AspectJ being in this phase. Developers no longer fear it for its perceived complexity but rather show curiosity about exploring the benefits it offers and eagerly want to use AspectJ.
Let's look at the underlying factors that caused AspectJ to enter this phase.
AspectJ followed a path to enlightenment (pardon the pun) by simplifying its adoption. New syntax and weaving models (in part due to merger with AspectWerkz—a project led by Jonas Bonér and Alexandre Vasseur) removed some of the bumpiest patches on the path. The new syntax choices delayed the use of the weaver as far as executing the application (and, used with Spring, eliminated the weaver altogether). Load-time weaving allowed the introduction of AspectJ without much fuss. Java 5 also made a huge difference with the introduction of annotations. Annotations allow a simple collaboration point between developers of the main-line business logic and developers of aspects. Annotations alleviate the difficulty of writing good pointcuts to a large degree by enabling course-grained pointcuts that identify fine-grained join points in the main-line code.
The promise of good tooling—especially the possibility of visualizing the interaction between aspects and classes—has been an important differentiator from similar technologies (such as metaprogramming). Although AspectJ's support for Eclipse has always been reasonable, it was never as good as that for Java. Part of the problem was fast innovation in the underlying Eclipse JDT, which kept raising user expectations. Furthermore, compilation speed and memory requirement have been less than optimal. Overall, there was a gap between potential and reality when it came to tooling. Lately, the AspectJ and AJDT teams have performed some amazing feats in optimizing the compilation process and IDE integration. The changes in the latest AJDT, where the JDT is woven with AspectJ functionality (using AspectJ itself) make development within Eclipse a pleasant and productive experience. With all these changes, any issues with tooling are a thing of past.
Spring AOP also needed to respond to user needs. Although proxy-based AOP lowered the adoption barrier compared to AspectJ's byte-code based AOP, Spring's programming model wasn't inviting. Aspects written using it were type-unsafe and verbose. As a result, most developers limited themselves to the aspects shipped as part of Spring and other frameworks. Spring responded by adopting the AspectJ programming model with a proxy-based implementation. This new possibility lets you use a subset of the AspectJ syntax without the need for a special compiler or weaver. This significantly reduced the barrier to writing custom aspects to meet the specific needs of an application. Here, too, annotation-based pointcuts helped remove whatever was left of the barrier to its adoption. Currently, Spring considers AspectJ to be its preferred programming model and has relegated the old model to a transitionary technology status. Spring's adoption of AspectJ also provided AspectJ a much needed context to grow.
Languages grow within a certain context. C grew in the context of operating system programming, C++ grew in context of UI programming, Java grew in the context of servlets (leading it to be the favored server-side language), and Ruby grew in the context of Rails. AspectJ lacked such a context. It has been used in real-time programming, UI programming, and server-side programming. As a result, there has been a dissipated effort to make AOP a mainstream technology. The Spring Framework has changed it all. It provided the right context—enterprise applications—for AOP to gain prominence.
AOP was already an integral part of Spring, helping with concerns such as transaction management, security, and monitoring. By using an elegant programming model offered by AspectJ, it paved the way for mass adoption.
The adoption of a new technology, especially with significantly new concepts such as AOP, is never easy. You need a path that allows a gradual introduction of the technology. Before AspectJ 5 and Spring AOP, the adoption path for AOP was steep.
Spring's proxy-based AOP with AspectJ syntax is a great way to start with AOP. It yields immediate benefits and provides experience with AOP. Spring even provides a few pre-built aspects to get you started. During this phase, you can start writing simple aspects based on the @AspectJ syntax applied using proxy-based AOP. Later, you can use byte-code-based weaving along with or as a replacement for the proxy-based AOP. Here, you can have several smaller steps available to manage risk. Initially, you can use aspects such as tracing and monitoring for development. Because you don't need to commit to using these aspects in production, there is little risk in trying them. With these aspects, load-time weaving is a great help; you don't need to modify your build system or use a special IDE, making the addition of aspects a much simpler task.
Next, you can begin using policy enforcement aspects. You can get feedback provided by the aspects about any policy violations while remaining uncommitted to their production use. In this phase, you can start using AJDT for immediate feedback right inside the IDE. During this process, you can vastly simplify the writing of the aspects using custom annotations—something you couldn't do before AspectJ 5. By this stage, you should be comfortable with the patterns and practices of AOP. This is the point at which you can make a judicious decision based on real experience.
In the last few years, practitioners have distinguished between Java the platform and Java the language. There is a growing recognition that Java the language isn't sufficient for productivity even considering the vast number of tools available for it. You need to choose some other language to gain a competitive advantage. At the same time, there is growing faith in the other part of Java the platform. With all the innovations in the VM as well as the overall platform (OSGi, mature libraries, IDEs), it's compelling to use the Java platform for many projects. Combining these factors has led to innovative new languages such as Groovy, JRuby, Scala, and Clojure on the Java platform. Today, it's not a shock to hear of a project using one of these new languages. As a result, the fear of new languages has gone down substantially. The use of multiple languages within the same project is also common. One of the negatives of AspectJ—that it's a new language—is no longer the case.
Even on the methodology front, there is a growing sense that OOP may have run its course. For today's complex problems, we need more power. We need to use OOP with something else: metaprogramming, functional programming, or aspect-oriented programming. Furthermore, you may use several additional methodologies along with OOP. For example, you may use Java with Scala to take the functional approach along with AspectJ to deal with crosscutting concerns. This Polyglot Programming (http://www.polyglotprogramming.com) approach uses multiple languages in the same application and is steadily gaining traction. AspectJ may have to adopt its join point model, which exclusively targets the Java language, to fit into the polyglot programming scenario. Fun times may lie ahead!
Selecting the required crosscutting points is one of the most critical and difficult tasks in writing aspects. Relying only on naming convention, type hierarchy, and package structure takes you quite a way. But in many case, defining a robust pointcut poses some difficulty. With the introduction of annotations in Java 5, AspectJ provides an easy and transparent way to select the join points you want. With annotations in play, aspect developers can expect class developers to mark program elements with annotations. It makes both camps happy—aspect developers can write simple pointcuts that can select program elements based on annotations they carry. On the other hand, class developers control the application of crosscutting functionality, because they choose what to annotate. The result is simplified and robust adoption of AOP.
The EJB framework appeared to provide a solution to modularizing crosscutting concerns. But most developers realize that the approach it offers is too heavyweight.
Various interceptor-based technologies promised to be alternatives to AOP. For example, EJB3 introduces interceptors as a new mechanism, a concept similar to AOP's advice—a definite step in the right direction, but lacking the join point model, which lies at the core of AOP.
Dynamic languages provide an alternative to AOP. But even with Groovy and Ruby, AOP has a place. Dynamic languages, despite the buzz surrounding them, are still new. As these languages mature and are used more seriously in enterprise applications, I expect AOP to gain prominence. After all, not many people thought anything was lacking in the Java programming language 10 years back! Interestingly, due to the availability of metaprogramming in dynamic languages, implementing AOP is easy.
For AspectJ, this phase is ongoing. It will be interesting to see how it unfolds.
This is a boring phase, where there is little hype. The technology is no longer cool and on the leading or bleeding edge. It starts to appear on resumes and job applications in a substantial way. The technology fulfills its promise of improved productivity, and developers use it for the problems where it's known to really work. Although it's boring to those who are looking for a shot of excitement, this phase is the most appropriate for mass adoption. This phase often includes interesting innovations, but they aren't a hallmark of the phase. Instead, the focus is on best (and worst) practices based on real experience in the technology's adoption and problem-specific premade solutions (libraries).
This is where the Java language is today. AOP and AspectJ should reach this level in a few years.
We can address the question of how real AOP is by looking at where it's being used. Let's see what kind of applications use AOP.
Enterprise applications need to address many crosscutting functionalities: transaction management, security, auditing, service-level agreement, monitoring, concurrency control, improving application availability, error handling, and so on. Many enterprise applications use AOP to implement these functionalities.
Virtually every project that uses Spring uses AOP. Many applications start with prewritten aspects supplied with Spring (primarily transaction management and security). But due to the @AspectJ syntax, writing custom aspects is becoming a common task. After reaching the limits of Spring AOP, many applications move toward AspectJ weaving. The typical trigger point for this change is crosscutting of domain objects or other forms of deeper crosscutting functionalities. At that time, it's common to start with the @AspectJ syntax (which is used with Spring's proxy-based AOP) along with the load-time weaver. Of course, applications that don't use Spring often use AspectJ weaving from the beginning.
The industry sectors in which AspectJ is used in production (with proxy-based and bytecode-based AOP) range from financial companies (banking, trading, hedge funds) and health care to various web sites (e-commerce, customer care, content providers, and so on). If you're implementing enterprise applications and using AOP, you're in good company.
The open source SpringSource dm Server (http://www.springsource.com/products/ dmserver) supports developing enterprise application based on OSGi. It uses AspectJ to implement various crosscutting functionalities, such as First Failure Data Capture (FFDC), context collection, tracing, and policy enforcement. The SpringSource tc Server (http://www.springsource.com/products/tcserver) uses AspectJ to implement monitoring of deployed applications. You can expect a lot more functionality to be implemented using AspectJ in both these products.
Application frameworks can use AOP effectively to target specific crosscutting functionalities while keeping their structure modularized. As discussed earlier, Spring provides crosscutting solutions such as transaction management and security through aspects. Furthermore, Spring includes aspects for injecting dependencies into domain objects. Frameworks that use AspectJ as their foundation have started to appear as well.
Spring Roo (http://www.springsource.org/roo) is an open source, lightweight, and customizable framework that includes interactive and IDEbased tooling to enable rapid delivery of high performance enterprise Java applications. It uses a round-tripping code generator along with AspectJ byte-code weaving to keep generated code separate from user-written code. By judiciously combining annotations with AspectJ's static and dynamic crosscutting, it offers a significant boost in developer productivity without tying the application to Spring Roo. Another AspectJ-based project—Magma (http://cwiki.apache.org/labs/magma.html)—is an Apache lab project that simplifies development of Java web applications. It internally uses AspectJ and exposes it to power users to improve developer productivity and produce maintainable software.
AspectJ makes implementing a flexible monitoring scheme a breeze. Therefore, many tools use AspectJ as the underlying technology. Glassbox (http://glassbox.sourceforge.net/glassbox/Home.html), an open source product, offers ready-to-use aspects and tools to help you get started with application-level monitoring and pinpoint potential bottlenecks. Another open source product, Perf4J (http://perf4j.codehaus.org), uses annotations along with AspectJ weaving to monitor applications. Yet another open source tool, Contract4J (https://github.com/deanwampler/Contract4J5), uses AspectJ to monitor contract violations.
Several commercial products also use AspectJ to implement monitoring solutions. SpringSource Application Management Suite (http://www.springsource.com/products/suite/ams) focuses on application-level monitoring such as the time taken by methods in the system specifically targeting Spring-based applications. It also includes functionality such as alerting and trend analysis to let you take corrective actions. JXInsight (http://www.jinspired.com/products/jxinsight) monitors applications to provide insight into potential performance bottlenecks. It uses AspectJ-based probes to weave into various technologies. MaintainJ (http://maintainj.com) uses aspects to monitor system execution and generates sequence diagrams.
AspectJ itself uses AspectJ to extend the JDT complier to support AspectJ constructs. AJDT uses AspectJ weaving through OSGi-based weaving service implemented by the Equinox Aspect project (http://www.eclipse.org/equinox/incubator/aspects/equinox-aspects-quick-start.php) to better integrate with the JDT in Eclipse. This recent change enabled AJDT to provide a much better user experience. Scala IDE for Eclipse also followed the same route to provide a better experience for Scala developers.
I hope this discussion has helped put AOP and AspectJ in perspective. Rather than being a niche product, AspectJ has long been considered a standard tool in the developer toolbox.
Here are some other Manning titles you might be interested in:
Spring Batch in ActionArnaud Cogoluegnes, Thierry Templier, Gary Gregory, Olivier Bazoud
Spring in PracticeWillie Wheeler, John Wheeler, and Joshua White
Spring in Action, Fourth EditionCraig Wells