Aspects in the Real World Applying AOSD techniques in large systems.

33
Aspects in the Real World Applying AOSD techniques in large systems

Transcript of Aspects in the Real World Applying AOSD techniques in large systems.

Aspects in the Real World

Applying AOSD techniques in large systems

Overview

AspectJ Case Studies IBM Websphere

Introduction to AspectWerkz Issues for commercial adoption Discussion

What are the best/worst uses of AOP? Is there a killer tool (or enhancement) still

needed? Advantages of AspectJ vs. HyperJ

(Homogeneous vs. Heterogeneous concerns)

Case Studies

IBM Websphere Using AOP to solve middleware complexity issues

Applying policies across product line Enabling optional features Efficient refactoring

Other Studies QuO – Programming QoS adaptive applications COMQUAD

Homogeneous Crosscutting Concerns Homogeneous Concern applies consistent

policy across code Tracing and Logging

Aspects are useful when dividing responsibility (component developers need not worry about implementing orthogonal policies in their code)

Monitoring and Statistics Error Capturing

Catch ‘throws’ join point

Aspect-driven homogeneous policies Intuitively it seems that Aspects are well-

suited to implementing tasks such as logging Question: is it worth re-engineering systems? IBM did some analysis of non-AO code

Admin component of Websphere 355 errors found (missing trace points, 33% of FFDC

entries incorrect Runtime component of Websphere

Missing trace points, 17% of FFDC entries incorrect

Heterogeneous Crosscutting Concerns Heterogeneous concern impacts multiple

places yet exhibits different behavior in each place

Using aspects to perform efficient refactoring Separate a feature of the system (EJB Support) Goal: Create a refactored system that can build

with or without EJBs Problem: Large code base with many hard to find

hooks into EJB code

Refactoring Process

Concern Modelling

Visualization

Concern-based queries

Refactoring (AO & OO)

AnalyzeQueryReport

Alter EJB Support pointcut definition

Run Query

RefactorComponent

Refactoring – Searching for Linkspublic aspect EJBSupportSeparation {

pointcut inEjbSupport() {within(T1) ||within(T2) ||...;

}

pointcut ejbSupportLink() {call(* T1.*(..)) ||call(* T2.*(..)) ||...;

}

declare warning :ejbSupportLink() && !inEjbSupport() :

"Link to EJB Support found.";}

public class Account {

    private int _accountNumber;

    private float _balance;

 

    public Account(int accountNumber) {

        _accountNumber = accountNumber;

    }

 

    public int getAccountNumber() {

        AccessController.checkPermission(

            new BankingPermission("accountOperation"));

        return _accountNumber;

    }

 

    public void credit(float amount) {

        AccessController.checkPermission(

            new BankingPermission("accountOperation"));

        _balance = _balance + amount;

    }

Sample Refactoring – Bank Account

Sample Refactoring – Bank Account Add empty aspect/pointcut

    private static aspect PermissionCheckAspect {

        private pointcut permissionCheckedExecution() :

            (execution(public int Account.getAccountNumber())

             || execution(public void Account.credit(float)))

            && within(Account);

 

        before() : permissionCheckedExecution() {

        }

    }

Sample Refactoring – Bank Account Add crosscutting functionality (+ Warning)// optional declare warning:

call(void AccessController.checkPermission(java.security.Permission)) && within(Account) && !within(PermissionCheckAspect) : "Do not call AccessController.checkPermission(..) from Account";

// end optional

private pointcut permissionCheckedExecution() : (execution(public int Account.getAccountNumber()) || execution(public void Account.credit(float)))&& within(Account);

before() : permissionCheckedExecution() { AccessController.checkPermission(

new BankingPermission("accountOperation"));}

Sample Refactoring – Bank Accountpublic class Account {     private int _accountNumber;     private float _balance;

    public Account(int accountNumber) {         _accountNumber = accountNumber;     }

    public int getAccountNumber() {         return _accountNumber;     }

    public void credit(float amount) {         _balance = _balance + amount;     }

    private static aspect PermissionCheckAspect {         private pointcut permissionCheckedExecution()             : (execution(public * Account.*(..))                && !execution(String Account.toString()))               && within(Account);         before() : permissionCheckedExecution() {             AccessController.checkPermission(                 new BankingPermission("accountOperation"));         }     } }

Results

AspectJ compiler worked with over 20,000 source files 10.5% faster than javac with no aspects 30-50% increase in compilation with aspects (rest

of build time unaffected) Queries are efficient when using CME

Case for Test Driven Development?

Peculiarities of AO Refactoring Approach towards crosscutting functionality

Prototype conventional solution first? Applicability of aspect's crosscutting

Limiting the scope of the aspects Coupling consideration

Minimize coupling between classes and aspects not as important

Placement of aspects Keep aspects closer to targets (even nested)

AspectWerkz

Dynamic AOP framework for Java Tailored for real world

JLS compatible Definition syntax in XML and/or Attributes Load time, runtime and static weaving Allows redefinition of aspects at runtime

AspectJ Example

aspect AsynchAspect { private ThreadPool m_threadPool = ...

Object around(): execution(void foo.bar.Baz.*(..)){ m_threadPool.execute(new Runnable() { public void run() { try { // proceed the execution in a new thread proceed(); } catch (Throwable e) { throw new WrappedRuntimeException(e); } }); return null; } }

AspectWerkz Example

class AsynchAspect extends Aspect { private ThreadPool m_threadPool = ...

/** @Around execution(void foo.bar.Baz.*(..)) */ Object execute(JoinPoint joinPoint) throws Throwable { m_threadPool.execute(new Runnable() { public void run() { try { // proceed the execution in a new thread joinPoint.proceed(); } catch (Throwable e) { throw new WrappedRuntimeException(e); } }); return null; } }

XML Definition syntax

<aspect class="samples.AsynchAspect"

deployment-model="perJVM">

<pointcut name="executePoint“

expression="execution(void foo.bar.Baz.*(..))“/>

<advice name="execute"

type="around"

bind-to=“executePoint"/>

</aspect>

Issues for commercial adoptionAs proposed by BEA

Systems Usability Agility Integration Expressiveness Performance Tool Support Aspect Container

Usability

JLS Compatibility Stays out of the way

Developer can code just as usual in favorite IDE. No immediate needs for custom plugins and specific tool

support.

Attribute definition Self-defined and self-contained aspects Easier to build reusable aspect libraries

XML definition Allows loose coupling between advice and pointcuts

Integration

How to weave the aspects? AW uses JVM-wide hook mechanism to control all

class loading (load-time weaving) Easier to work with application servers Weaving is platform/vendor independent

AW also does runtime weaving Uses two-phase weaving (to prepare classes) Multi-weaving. Classes can be woven, rewoven or

unwoven at any point Slower startup time (scales poorly with large codebase

and freely defined pointcuts)

Tool Support

AspectWerkz currently lacks good tool support apart from: Plugin for the Maven build system Support for debugging aspects within an IDE JUnit extension

Standardization of attributes in JSR-175 will bring many tools for working with metadata

Dynamicity vs. Performance

AspectWerkz is designed to have a dynamic runtime model, which means that the user can redefine his aspect system at runtime.

To support a dynamic runtime model the framework makes use of delegation and reflection and introduces a level of indirection to allow the aspects and target classes to be loosely coupled.

Runtime compiler, which has similarities with JIT compilers in modern JVMs, detects advice chains that are often executed and creates a custom class on the fly that invokes the advice chain and the target method statically.

AspectWerkz makes heavy use of caching and lazy loading to improve the runtime performance

Discussion

Best mechanism for weaving aspects Aspects as language extension or pure Best place to use aspects? AOP refactoring Test-Driven Development via AOP Need for AOP patterns

Addendum – AspectJ Design Patterns http://www.cs.ubc.ca/~jan/AODPs/

QuO toolkit

The QuO Toolkit provides support for building systems with adaptive QoS

Four main entities in the QuO model Contracts: used to define adaptation policy System Condition Objects: used to monitor the environment Callbacks: used for middleware, system, and out-of-band

application adaptation Delegates: used for in-band application adaptation

Quality of Service issues in Distributed Applications Remote invocations

Can take longer than local calls Might fail when local call doesn’t Might expose security issues

Impact of these factors varies during runtime due to environment

Impact of the distributed application on the environment (changing operational mode)

Handling QoS

Initial idea: modify code to examine situation and act accordingly Violates distributed object model Affects application code in many places

Providing QoS management and control features in the system Only partially successful since each application

has specific QoS needs

QoS as an Aspect

Build QoS management as an aspect and weave the result between application and middleware aspect code has access to application-specific,

middleware, and system information and controls without having to modify either the application logic or the underlying distribution middleware

QuO Aspect Model

Delegates Compile aspect into delegate which acts as proxy for calls

to remote object and adds desired behavior to invocation Advice Model

applied to a particular method of a particular interface as specified in CORBA IDL

Join points METHODENTRY, PREMETHODCONTRACTEVAL, METHODCALL,

POSTMETHODCONTRACTEVAL, METHODRETURN Advice

BEFORE, AFTER, INPLACEOF, ONEXCEPTION

QuO Example

Document Server// Document Server IDL

module Document {

typedef string Query;

typedef string DocumentData;

typedef sequence<octet> Image;

interface Server {

DocumentData get_document(in Query q);

Image get_image(in Query q);

);

);

QoS Strategy Operate Normally OR Compress images OR Give up

QuO Example Aspectbehavior CompressImage (){

qosket CompressImageDelegateQosket qk;ivar onserver quo::ValueSC allow compression;

Document::Image Document::Server::get_image(in Document::Query q) {return value Document::Image rval;inplaceof PREMETHODCONTRACTEVAL onclient {}before METHODCALL onclient {

q = qk.add_alloweompression{q);}after METHODENTRY onserver {

allow_compression.booleanValue(qk.get_allow_compression(q));)after POSTMETHODCONTRACTEVAL onserver {

region NetworkLoad {region CriticalLoad {

throw CORBA::NORESOURCES;}region Compress {

rval = qk.compress_image(rval);}region NoCompress {

throw CORBA::NO_RESOURCES;)

) )

)

Concern Manipulation Environment Tools to support usage of AOSD throughout

software lifecycle Concern Composition Component

Composes/weaves different concerns in any of the supported artifact languages supported by the CME.

Concern Manager Models software in terms of arbitrary concerns and their

interrelationships. Concern Assembler Toolkit Concern Informant Toolkit Pattern Underlying Matcher