1
Methodology: The AOP Refactoring Process Aspect-Oriented Refactoring of the Apache Cocoon Shared-Object Resource Allocation System Jeff Dalton Advisor: David G. Hannay, Union College Client: Robert Berry, IBM Java Technology Centre, Hursley, UK Background: aspectj. aspectj. & AOP AspectJ is a small and well-integrated extension to Java that weaves java byte code and outputs .class files compatible with any JVM. What is Aspect Oriented Programming? Concern – “a specific requirement or consideration that must be addressed in order to satisfy the overall system goal.” AOP is a programming language mechanism that extends Object-Oriented Programming in order to achieve modularity and the ‘separation of concerns’. AOP introduces a new unit of modularization, an aspect , that captures behaviors that affect multiple classes (a crosscutting concern) into reusable modules. What are aspects? Aspects are: concerns that crosscut [design level] a programming construct [implementation level] Aspects = pointcut + advice + inter-type declarations •Joinpoint: a principle point in the execution of the software system •Pointcut: predicate matching on joinpoints (where) •Advice: behavior that should be triggered at joinpoints, selected using a pointcut (what) •Inter-type Declarations: Fields and methods that the aspect manages on behalf of other types AspectJ’s goal is to support the programmer in cleanly separating components and aspects from each other by providing mechanisms that make it possible to abstract and compose them to produce the overall system Abstract Aspect-oriented programming (AOP) enables developers to develop and manage 'cross-cutting concerns' unrelated to the primary function of the system component. Using AOP, these concerns can then be introduced to the base component easily and in a structured manner. Other benefits of using AOP include the creation of software that is easier to understand and modify. Caching, a common and effective technique to improve the performance of applications and middleware, is such a cross- cutting concern. We explore this by refactoring a complex web application, Apache Cocoon, using AOP to introduce a caching mechanism. The goal is to retain the original external behavior, while removing complexity and adding flexibility in the caching system. The development of the AspectJ language and compiler allows the application of this methodology on the existing base of Java-based web applications without requiring new infrastructure. This project takes the next step by using AspectJ to simplify and extend the caching system in a large and complex XML-based website publishing system; it explores the potential difficulties associated with using AspectJ to accomplish this task and considers the effect that the application architecture has on the aspect-oriented refactoring process. Background: Refactoring Refactoring – a change made to the internal structure of the software to make it easier to understand and cheaper to modify without changing its observable behavior Background: Apache Cocoon A dynamic multi-channel web publishing platform “Apache Cocoon is a web development framework built around the concepts of separation of concerns and component-based web development.” – Cocoon Goal: The separation of content, style, logic and management functions in an XML content based web site (and web services). Usage example: Take data from a database and publish the content onto a web portal in HTML, PDF, and WHTML formats simultaneously. Step 2: Write Caching Aspects privileged public aspect CachingAspect { /* Ascii art generator */ declare parents: org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator implements CacheableProcessingComponent; public Serializable org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator.generateKey() { return this.inputSource.getURI(); } public SourceValidity org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator.generateValidity() { return this.inputSource.getValidity(); } .... ‘Mixin’ it up: Use AOP design patterns to condense reusable code public interface SharedCacher extends CacheableProcessingComponent { public SourceValidity generateValidity(); public java.io.Serializable generateKey(); } public aspect SharedCacherAspect { declare parents: (org.apache.cocoon.serialization.FOPSerializer|| org.apache.cocoon.serialization.iTextSerializer|| org.apache.cocoon.transformation.FragmentExtractorTransformer|| org.apache.cocoon.serialization.SVGSerializer|| org.apache.cocoon.serialization.AbstractTextSerializer ) implements SharedCacher; public Serializable SharedCacher.generateKey() { return "1"; } public SourceValidity SharedCacher.generateValidity() { return NOPValidity.SHARED_INSTANCE; } } Specialized reusable class Classes with same caching behavior Introduce Interface Introduce Methods Analysis & Observations Question: How should you structure your application to simplify AO extendibility? Good coding practice makes AO adoption easier -Standard variable naming Disparate names: LexicalSource, GrammarSource, etc. needed to be refactored to “InputSource” before they could be used to remove code via AOP. Standard accessor methods are required to reduce introductions through Mixins. - Example: One case needed getInputSource() -But how are we supposed to know we need these when writing the software? - We can’t know. The lesson : In some cases you need to perform Object-Oriented refactoring in order to allow AOP to reduce code duplication. Open Questions In a component architecture, do we define crosscutting concerns? Do we examine each block individually or the system as a whole? What do you do if it is a crosscutting concern in the system but not within the block? This points to a larger problem How should aspects be viewed on a design level? Future Work Integrate the AspectJ Compiler into the Cocoon build process so that the AO caching solution can be deployed on a Tomcat web server. Use AOP to refactor the internal object store within Cocoon. This is an ‘internal cache’ where classes can store objects for later retrieval. This is a very closely related to this project since the caching system is just a thin wrapper around this store. An event-driven ‘inverted’ AOP caching system Build a caching system that uses AOP to handle ‘Avalon’ events and perform the proper cache invalidations. AOP solves the design problem of where to define the caching strategy. Conclusions Many more opportunities for AOP in Cocoon! Modifications to the AspectJ language and implementation would make the process easier, but it is still viable today. Summary: Abstracted 39 implementations of CacheableProcessingComponent Used AOP to condense and remove 24 methods from the base implementation. Removed all of the caching code into a single AOP package. Example: Duplicate code: public Serializable org.apache.cocoon.transformation.LexicalTransfo rmer.generateKey() { return this.lexiconSource.getURI(); } public Serializable org.apache.cocoon.transformation.ParserTransfor mer.generateKey() { return this.grammarSource.getURI(); } AOP is another tool, it not a ‘silver bullet’ and conventional refactoring methodologies and tools are still necessary. References & Resources Apache Cocoon Project http://cocoon.apache.org/ AspectJ Project - http://www.aspectj.com/ Project website – http://cs.union.edu/~daltonj/ Thanks to the AspectJ team at Hursley for their valuable assistance and for providing some background information on AOP. Step 1: Identify locations – “Aspect Mining” Used AspectJ to define a compiler warning in order to identify locations in Cocoon that implement the CacheableProcessingComponent abstract interface. public aspect ExploreCaching { declare warning: staticinitialization(org.apache.cocoon.caching.CacheableProcess ingComponent+) && !within(org.apache.cocoon.caching..*): "Class implements cacheable"; } Step 3: Remove References and Compile Step 4: Testing & Verification In Progress Integrating AspectJ into Cocoon Ant build process

Methodology: The AOP Refactoring Process

  • Upload
    sylvia

  • View
    24

  • Download
    2

Embed Size (px)

DESCRIPTION

Step 1: Identify locations – “Aspect Mining” Used AspectJ to define a compiler warning in order to identify locations in Cocoon that implement the CacheableProcessingComponent abstract interface. public aspect ExploreCaching { - PowerPoint PPT Presentation

Citation preview

Page 1: Methodology:  The AOP Refactoring Process

Methodology: The AOP Refactoring Process

Aspect-Oriented Refactoring of the Apache Cocoon Shared-Object Resource Allocation System

Jeff Dalton

Advisor: David G. Hannay, Union College

Client: Robert Berry, IBM Java Technology Centre, Hursley, UK

Background: aspectj.aspectj. & AOP

AspectJ is a small and well-integrated extension to Java that weaves java byte code and outputs .class files compatible with any JVM.

What is Aspect Oriented Programming?

Concern – “a specific requirement or consideration that must be addressed in order to satisfy the overall system goal.”

AOP is a programming language mechanism that extends Object-Oriented Programming in order to achieve modularity and the ‘separation of concerns’.

AOP introduces a new unit of modularization, an aspect, that captures behaviors that affect multiple classes (a crosscutting concern) into reusable modules.

What are aspects?Aspects are:

concerns that crosscut [design level]

a programming construct [implementation level]

Aspects = pointcut + advice + inter-type declarations

•Joinpoint: a principle point in the execution of the software system

•Pointcut: predicate matching on joinpoints (where)

•Advice: behavior that should be triggered at joinpoints, selected using a pointcut (what)

•Inter-type Declarations: Fields and methods that the aspect manages on behalf of other types

AspectJ’s goal is to support the programmer in cleanly separating components and aspects from each other by providing mechanisms that make it possible to abstract and compose them to produce the overall system

Abstract

Aspect-oriented programming  (AOP) enables developers to develop and manage 'cross-cutting concerns' unrelated to the primary function of the system component.  Using AOP, these concerns can then be introduced to the base component easily and in a structured manner.  Other benefits of using AOP include the creation of software that is easier to understand and modify.  Caching, a common and effective technique to improve the performance of applications and middleware, is such a cross-cutting concern.  We explore this by refactoring a complex web application, Apache Cocoon, using AOP to introduce a caching mechanism.  The goal is to retain the original external behavior, while removing complexity and adding flexibility in the caching system.  The development of the AspectJ language and compiler allows the application of this methodology on the existing base of Java-based web applications without requiring new infrastructure. This project takes the next step by using AspectJ to simplify and extend the caching system in a large and complex XML-based website publishing system; it explores the potential difficulties associated with using AspectJ to accomplish this task and considers the effect that the application architecture has on the

aspect-oriented refactoring process.        

Background: Refactoring

Refactoring – a change made to the internal structure of the software to make it easier to understand and cheaper to modify

without changing its observable behavior  

Background: Apache Cocoon

A dynamic multi-channel web publishing platform

“Apache Cocoon is a web development framework built around the concepts of separation of concerns and component-based web development.”

– CocoonGoal:

The separation of content, style, logic and management functions in an XML content based web site (and web services).

Usage example:Take data from a database and publish the content onto a web portal in HTML, PDF, and WHTML formats simultaneously.

Step 2: Write Caching Aspects

privileged public aspect CachingAspect {/* Ascii art generator */ declare parents: org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator implements CacheableProcessingComponent;

public Serializable org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator.generateKey() { return this.inputSource.getURI(); }

public SourceValidity org.apache.cocoon.generation.asciiart.AsciiArtSVGGenerator.generateValidity(){ return this.inputSource.getValidity(); } ....

‘Mixin’ it up: Use AOP design patterns to condense reusable code

public interface SharedCacher extends CacheableProcessingComponent{

public SourceValidity generateValidity();public java.io.Serializable generateKey();

}public aspect SharedCacherAspect {declare parents: (org.apache.cocoon.serialization.FOPSerializer||

org.apache.cocoon.serialization.iTextSerializer||org.apache.cocoon.transformation.FragmentExtractorTransformer||org.apache.cocoon.serialization.SVGSerializer||org.apache.cocoon.serialization.AbstractTextSerializer) implements SharedCacher;

public Serializable SharedCacher.generateKey() {return "1";

}public SourceValidity SharedCacher.generateValidity() {

return NOPValidity.SHARED_INSTANCE; }}

Specialized reusable class

Classes with same caching behavior

Introduce Interface

Introduce Methods

Analysis & ObservationsQuestion:How should you structure your application to simplify AO extendibility?

Good coding practice makes AO adoption easier-Standard variable naming Disparate names: LexicalSource, GrammarSource, etc. needed to be refactored to “InputSource” before they could be used to remove code via AOP.

Standard accessor methods are required to reduce introductions through Mixins.

- Example: One case needed getInputSource() -But how are we supposed to know we need these when writing the software? - We can’t know.

The lesson: In some cases you need to perform Object-Oriented refactoring in order to allow AOP to reduce code duplication.

Open QuestionsIn a component architecture, do we define crosscutting concerns?

Do we examine each block individually or the system as a whole?

What do you do if it is a crosscutting concern in the system but not within the block?

This points to a larger problem

How should aspects be viewed on a design level? 

Future Work Integrate the AspectJ Compiler into the Cocoon build process so that the AO caching solution can be deployed on a Tomcat web server.

Use AOP to refactor the internal object store within Cocoon. This is an ‘internal cache’ where classes can store objects for later retrieval. This is a very closely related to this project since the caching system is just a thin wrapper around this store.

An event-driven ‘inverted’ AOP caching systemBuild a caching system that uses AOP to handle ‘Avalon’ events and perform the proper cache invalidations.

AOP solves the design problem of where to define the caching strategy.

 

Conclusions Many more opportunities for AOP in Cocoon!

Modifications to the AspectJ language and implementation would make the process easier, but it is still viable today.

Summary:Abstracted 39 implementations of CacheableProcessingComponent

Used AOP to condense and remove 24 methods from the base implementation.

Removed all of the caching code into a single AOP package.

Example: Duplicate code:public Serializable org.apache.cocoon.transformation.LexicalTransformer.generateKey() {

return this.lexiconSource.getURI();}public Serializable org.apache.cocoon.transformation.ParserTransformer.generateKey() {

return this.grammarSource.getURI();}

AOP is another tool, it not a ‘silver bullet’ and conventional refactoring methodologies and tools are still necessary.

References & Resources Apache Cocoon Project http://cocoon.apache.org/

AspectJ Project - http://www.aspectj.com/

Project website – http://cs.union.edu/~daltonj/

Thanks to the AspectJ team at Hursley for their valuable assistance and for providing some background information on AOP.

Step 1: Identify locations – “Aspect Mining”

Used AspectJ to define a compiler warning in order to identify locations in Cocoon that implement the CacheableProcessingComponent abstract interface.

public aspect ExploreCaching { declare warning: staticinitialization(org.apache.cocoon.caching.CacheableProcessingComponent+) && !within(org.apache.cocoon.caching..*): "Class implements cacheable";

}    

Step 3: Remove References and Compile

Step 4: Testing & Verification

In ProgressIntegrating AspectJ into Cocoon Ant build process