Aspect Oriented Programming in JAsCo Wim Vanderperren Object Oriented Programming [C++, Java, Smalltalk, Python,…] JAsCo 6 November 2015 | pag.

Download Report

Transcript Aspect Oriented Programming in JAsCo Wim Vanderperren Object Oriented Programming [C++, Java, Smalltalk, Python,…] JAsCo 6 November 2015 | pag.

Aspect Oriented Programming in JAsCo
Wim Vanderperren
Object Oriented
Programming
[C++, Java, Smalltalk, Python,…]
JAsCo
6 November 2015 | pag. 2
Class A
Class D
Class B
Class C
Component-Based
Programming
[Java Beans, EJB, .NET, CORBA,…]
COMP A
COMP D
Glue Code
COMP B
JAsCo
6 November 2015 | pag. 3
COMP C
Crosscutting concerns
XML Parsing in Apache Tomcat
[Picture taken from the aspectj.org website]
Good modularity:
handled by code in one class
JAsCo
6 November 2015 | pag. 4
Crosscutting concerns
Logging in Apache Tomcat
BAD modularity:
[Picture taken from the aspectj.org website]
handled by code that is scattered over almost all
classes
JAsCo
6 November 2015 | pag. 5
Aspect-Oriented
Programming
[AspectJ, AspectC++, DJ, ConcernJ,Soul/AOP,…]
Logging in Apache Tomcat
joinpoint
…
pointcut
Logging
Aspect
JAsCo
6 November 2015 | pag. 6
Combining CBSE and
AOSD
• Component-Based Software Engineering
(CBSE):
– Goal: Increase reuse.
– BUT: Suffers greatly from crosscutting concerns.
• Aspect-Oriented Software Development (AOSD):
– Goal: Increase modularity.
– BUT: Suffers from limited reusability and
compositional power.
• Combination of CBSE and AOSD allows
achieving the best of both worlds!
JAsCo
6 November 2015 | pag. 7
AOP for CBSE:
Requirements
• Language requirements:
–
–
–
–
General purpose
Component communication
Independent aspects
Expressive aspectual composition mechanism
• Technology requirements:
–
–
–
–
Not dependent on source code
No invasive changes at aspect application time
First class aspects at run-time
Dynamic
JAsCo
6 November 2015 | pag. 8
JAsCo Language
• New AOP language (extension of JAVA)
– Reusable Aspect Beans
– Explicit Connectors
• Instantiating aspect beans
• Specifying combinations of aspects/components
AspectJ
JAsCo
6 November 2015 | pag. 9
JAsCo
class AccessManager {
private PermissionDb p_db = ….
private User user = null;
void login(User user, String pass) {}…
call, cflow,
withincode, target
hook AControl {
Abstract method parameter
Deploy
AControl(triggeringmethod(..args)) {
execution(triggeringmethod); }
isApplicable() {
return !p_db.isRoot(user);}
around() {
if(p_db.check(user,thisJoinPoint))
return proceed();
around,
around throwing,
else throw new AccessException();
around returning, after, after
}
throwing, after returning
}
}
JAsCo
6 November 2015 | pag. 10
JAsCo Language
connector AccessConnector {
AccessManager.AControl hook = new
AccessManager.AControl(
Abstract* Printer.*(*));
pointcut
}Triggering condition
JAsCo Aspect Beans: Hook constructor
• Specifies when to trigger the hook (together
with isApplicable)
• Signature specifies one or more abstract
method parameters that are bound to concrete
methods later on.
• Arguments of abstract method parameters have
a scope that extends all over the hook.
• Example:
aHook(m1(String s, int i),m2(..args),m3(PrintJob pj, ..args2) {
…}
JAsCo
6 November 2015 | pag. 11
JAsCo Aspect Beans: Hook constructor
body
• Several hook constructor body constructs are available:
– execution(x): Evaluates to true when method x is executed.
– cal(x)l: Evaluates to true when method x is invoked. (NYI)
– cflow(x): Evaluates to true when the currently executing method is in the
control flow method x. (Delimiter)
– withincode(x): Evaluates to true when method x is direct caller of the
currently executing method . (Delimiter)
– target(x): Evaluates to true when dynamic type of the object where a
method has been invoked upon is x or a subclass of x . (Delimiter)
• Examples:
– execution(method1) && cflow(method2)
– execution(method1) && ! cflow(method2)
– execution(method1) && ( ! (cflow(method2) ||
withincode(method3)))
– execution(method1) && target(java.util.Vector)
JAsCo
6 November 2015 | pag. 12
JAsCo Aspect Beans: Hook isApplicable
method
• Optional method
• Specifies when to trigger the hook in plain
Java.
• Allows to specify dynamic and
programmatic hook triggering conditions.
• Joinpoint reflection available.
JAsCo
6 November 2015 | pag. 13
JAsCo Aspect Beans: Hook advices
– Specifies the behavior that should be executed
whenever both the isApplicable method and hook
constructor evaluate to true.
– Described using plain Java.
– Are able to access arguments of abstract method
parameters.
– Seven kinds of advices are available:
• before and after: Allow to execute some behavior before or
after the encountered method joinpoint. (Have no return
value)
• around: Allows to wrap the original execution of method
joinpoint. Similar to the AspectJ around advice. (Has a
return value)
• after throwing/Around throwing: Allows to intercept the
throwing of an exception at the target joinpoint.
• after returning/Around returning: Allows to intercept the
returning of an object of a specific type at the current
joinpoint.
JAsCo
6 November 2015 | pag. 14
JAsCo Aspect Beans: Hook
advices (2)
• Around advice:
• Has a return value
• Allows to invoke proceed
around() {
if(p_db.check(currentuser,thisJoinPoint.getName()))
return proceed();
else throw new AccessException();
}
JAsCo
6 November 2015 | pag. 15
Around (2)
• Three kinds of proceed:
– proceed()
– proceed(Object target, Object[] args)
– proceed(same args as call or execution
pointcut designator)
hook hookname(method(int i)) {
execution(method);}
around() {
return proceed(i*0.9);
}
JAsCo
6 November 2015 | pag. 16
JAsCo Aspect Beans: Hook
advices (2)
• After Throwing:
after throwing(IOException ex) {
log (ex.getMessage());
}
after throwing(RuntimeException ex) {
log (“runtime exception occurred!!!”);
shutdown();
}
• Around Throwing
• Return value and Proceed supported
around throwing(IOException ex) {
log (ex.getMessage());
return proceed(); //invokes next in advice chain
}
around throwing(RuntimeException ex) {
log (“runtime exception occurred!!!”);
throw ex;
}
JAsCo
6 November 2015 | pag. 17
JAsCo Aspect Beans: Hook
advices (3)
• After Returning:
after returning(String s) {
System.out.println(“returned “+s);
}
• Around Returning
• Return value and Proceed supported
around returning(int price) {
System.out.println(“returned “+price);
return price*discountPercentage;
}
JAsCo
6 November 2015 | pag. 18
JAsCo aspect beans: other
features
• Aspect bean & hook inheritance
• global keyword to access aspect bean context
• thisJoinPointObject keyword
– Refers to target Object
– Type is
• Object (no target pointcut designator)
• Type of target pointcut designator (e.g. target(java.util.Vector)
• thisJoinPoint keyword for joinpoint reflection:
Example:
JAsCo
6 November 2015 | pag. 19
before() {
log(“Executing”+ thisJoinPoint.getName() + " IN “
+ thisJoinPoint.getClassName());
if(thisJoinPointObject!=null)
log(“Object executed: ”+thisJoinPointObject);
}
Connectors: Basic Syntax
(1)
static connector PrintAccessControl {
AccessManager.AccessControl control =
new AccessManager.AccessControl(* Printer.*(*));
//optional:
control.around();
}
JAsCo
6 November 2015 | pag. 20
Connectors: Subtype
Pattern (2)
• Selects any dynamic subtype of given
class or interface.
static connector PrintAccessControl {
AccessManager.AccessControl control =
new AccessManager.AccessControl(*IPrintable.*+(*));
//optional:
control.around();
}
JAsCo
6 November 2015 | pag. 21
Connectors: Meta-Data Pattern
(3)
• Instantiating depending on meta-data aka
annotations (Java 5):
static connector GenericAccessControl {
AccessManager.AccessControl control =
new AccessManager.AccessControl(@secure * *.*(*));
//optional:
control.around();
}
JAsCo
6 November 2015 | pag. 22
Connectors:hooks on
events (4)
static connector PrintAccessControl {
AccessManager.AccessControl control =
newAccessManager.AccessControl(
{
* Printer.*(*),
onevent Fax.jobFinished(JobEventInfo)
});
}
JAsCo
6 November 2015 | pag. 23
Connectors: Controlling precedence
(5)
static connector PrintAccessControl {
AccessManager.AccessControl hook1 =
new AccessManager.AccessControl(* Printer.*(*));
LockingManager.LockControl hook2 =
new LockingManager.LockControl(* Printer.*(*));
hook1.around();
hook2.around();
}
hook1.around() {
...
proceed();
...
hook2.around() {
}
...
proceed();
...
}
JAsCo
6 November 2015 | pag. 24
originalMethod()
Connectors: Combination Strategies
• Enables more advanced aspect
combinations than ordering.
• Mainly designed as a kind of filter on
applicable hooks.
• Reusable.
• Easily extensible.
public interface CombinationStrategy {
public HookList validateCombinations(HookList);
}
JAsCo
6 November 2015 | pag. 25
Twin Combination Strategy
public class TwinCombinationStrategy
implements CombinationStrategy {
private Object hookA,hookB;
TwinCombinationStrategy(Object a, Object b) {
this.hookA=a;
this.hookB=b;
}
HookList validateCombinations(HookList list) {
if(!list.contains(hookA))
list.remove(hookB);
return list;
}
}
JAsCo
6 November 2015 | pag. 26
Applying the combination
strategy
static connector PrintAccessControl {
AccessManager.AccessControl control =
new AccessManager.AccessControl(* System.*(*));
logger.FileLogger logging =
new logger.FileLogger(* System.*(*));
logging.setLogText(“Executing: “);
addCombinationStrategy(
new TwinCombinationStrategy(control,logging));
logger.before();
control.around();
logger.after();
}
JAsCo
6 November 2015 | pag. 27
Automatically create multiple hook
instances
• Normally, only one hook instance is created for each
hook instantiation expression.
• In some cases however, multiple hook instances are
required for particular join points, sometimes even at the
same time.
• Is supported by 7 instantiation constructs:
–
–
–
–
–
–
perall : New hook instance each time the hook is triggered.
perobject : New hook instance for each thisJoinPointObject.
perclass : New hook instance for each class.
permethod : New hook instance for each method.
perthread : One hook instance for each thread.
percflow : Similar to the AspectJ counterpart. A new hook
instance for each control flow through a joint point where the
hook is triggered.
– per(IAspectFactory_className): Custom aspect factory for
automatically instantiating new hooks.
JAsCo
6 November 2015 | pag. 28
JAsCo Connectors: Hook
instantiations
• Automatically create multiple hook instances:
– Example:
static connector PrintAccessControl {
perobject AccessManager.AccessControl control =
new AccessManager.AccessControl(void Printer.Print(File));
}
For each instance of class printer, a new hook
instance will be instantiated.
JAsCo
6 November 2015 | pag. 29
JAsCo Connector Language: Advanced
concepts
• Initializing hook instances
– After instantiating a hook, it is possible to explicitly initialize some
of its data values.
– Imagine LogHook contains a setLoggingText method, which
allows to set a specific logging text.
– Example:
static connector LoggingConnector {
Logger.LogginHook logging =
new Logger.LoggingHook(void Printer.Print(File));
logging.setLoggingText(“Output”);
}
JAsCo
6 November 2015 | pag. 30
Explicitly initialize hooks instances with specific
values.
JAsCo Connector Language: Advanced concepts
• Static connector:
– All hooks are automatically triggered, despite of the specific
thisJoinPointObject.
– When omitted, specific thisJoinPointObjects need to be added manually,
in order to trigger the hook behavior => Instance Based Aspect
Application
• Connector reflection:
– The connector API allows to query a connector for various
properties
• addInstance(Object) : Add a specific object instance to trigger
on (see static connector)
• getHooks() : Return the list of hooks
• setEnabled(boolean) : Allows to enable or disable a connector
at run-time.
• isEnabled() : Is the connector enabled?
• …
JAsCo
6 November 2015 | pag. 31
JAsCo Refinable Methods
class DataPersistence {
hook Backup {
Backup(triggeringmethod(..args)) {
execution(triggeringmethod); }
isApplicable() {
// true when changed since last visit }
before() {
Writer writer = …
writer.writeObject(getDataMethod());
}
refinable Object getDataMethod();
}
}
JAsCo
6 November 2015 | pag. 32
Abstract method parameter
connector PersistenceConnector {
Persistence.Backup hook = new
DataStorePersistence.Backup(
Abstract
pointcut
* DataStore.set*(*));
}Triggering condition
refining DataPersistence.Backup
for DataStore {
public Object getDataMethod() {
DataStore d = thisJoinPointObject;
return d.getData();
}
}
JAsCo Aspect Beans: Refinable
methods
• Methods that are not implemented in the aspect,
but have to be implemented (refined) later on:
– In the connector (inline)
– In a refining class
• Can have default implementation in case no
implementation is given in the connector.
//without default implementation
refinable private Object getDataMethod();
//with default implementation
public refinable Object getDataMethod() {
if(thisJoinPointObject implements Serializable)
return thisJoinPointOject;
else return null;
}
JAsCo
6 November 2015 | pag. 33
Implementing Refinable Methods:
Inline implementation
• Hook instantiations and refinable methods:
– All refinable methods can be implemented in the
connector.
– Syntax is similar to anonymous classes in Java.
– thisJoinPointObject, thisJoinPoint and thisHook
keywords are available
connector PersistenceConnector {
Persistence.Backup hook = new
DataStorePersistence.Backup(* DataStore.set*(*)) {
private Object getDataMethod() {
return thisJoinPointObject;
}
};
}
JAsCo
6 November 2015 | pag. 34
Implementing Refinable
Methods: In a refinement class
• thisJoinPointObject refers to refining target
• thisHook keyword refers to the hook
• thisJoinPoint keyword refers to the current
joinpoint
• Late Binding
• Inline implementation has precedence
refining DataPersistence.Backup
for DataStore {
public Object getDataMethod() {
DataStore d = thisJoinPointObject;
return store.getData();
}
}
JAsCo
6 November 2015 | pag. 35
JAsCo Technology
Technology Requirements
Review
• Technology requirements:
– Not dependent on source code
– No invasive changes at aspect application
time
– First class aspects at run-time
– Dynamic
JAsCo
6 November 2015 | pag. 37
JAsCo Technology (1)
• New Component Model with traps built-in.
• Enables run-time aspect application and
removal.
• Backward compatible: Automatic
transformation from Java Beans to JAsCo
beans.
JAsCo
6 November 2015 | pag. 38
JAsCo Technology (2)
Hook1
Connector1
JAsCo
Component
method1
method2
Hook2
traps
ConnectorRegistry
event 1
Connector2
JAsCo
6 November 2015 | pag. 39
Hook3
JAsCo Dynamic AOP
•
•
•
•
•
•
Central Connector Registry
Remotely adding/removing aspects
Precedence Strategies
Combination Strategies
Applying Aspects on Instances
Dynamic Wildcard Matching
JAsCo
6 November 2015 | pag. 40
JAsCo Dynamic AOP
•
•
•
•
•
•
Central Connector Registry
Remotely adding/removing aspects
Precedence Strategies
Combination Strategies
Applying Aspects on Instances
Dynamic Wildcard Matching
JAsCo
6 November 2015 | pag. 41
Optimizing Dynamic AOP
• Two main parts:
– Interception System
– Aspect Interpreter
• Improving by:
– HotSwap
– Jutta
JAsCo
6 November 2015 | pag. 42
HotSwap: Optimizing the Interception
System (1)
• Run-time Instrumentation using Custom
Framework
• Only traps at methods where aspects are
applied
• Aspects added/removed dynamically →
corresponding traps added/removed by
hotswapping classes if necessary
• Two Systems:
– Java 1.4 JDI HotSwap
– Java 1.5 Instrumentation API
JAsCo
6 November 2015 | pag. 43
HotSwap: Optimizing the Interception
System (2)
HotSwap 1 (JDI)
• Benefits:
– Run-time overhead dramatically decreased.
• Drawbacks HotSwap:
– Installing traps takes some time.
– Less portable (requires JVM 1.4+).
– JVM has to run in debugging mode.
– Runs 2 JVMs
JAsCo
6 November 2015 | pag. 44
HotSwap: Optimizing the Interception
System (3)
HotSwap 2 (JPLIS)
• HotSwap using Java 1.5 instrumentation
API, available since JAsCo 0.6
• Benefits:
– Run-time overhead dramatically decreased
– Less cumbersome than HotSwap 1
• Drawbacks HotSwap 2:
– Installing traps takes some time.
– Less portable (requires JVM 1.5+).
JAsCo
6 November 2015 | pag. 45
Jutta: Optimizing Aspect Interpreter
(1)
BASE APP
jp1
jp2
jp3
jp4
JAsCo
6 November 2015 | pag. 46
• Jutta: Just in time
compiler for AOP
• Generates highly
optimized code
fragment (in byte
code) for each
joinpoint
• Lazy generation
• Invalidated when
aspects are
added/removed
Jutta: Optimizing Aspect Interpreter
(2)
• Example code fragment (Java
counterpart):
public Object executeJoinpoint(Joinpoint jp) {
Object result = null;
hook1.before(jp);
hook2.before(jp);
try {
result=hook0.around();
} catch(Exception ex) {
hook1.after_throwing(ex,jp);throw ex;}
if(hook7.isApplicable(jp)) hook7.after();
return result;
}
JAsCo
6 November 2015 | pag. 47
Jutta: Optimizing Aspect Interpreter
(3)
• Generating the code fragment takes some
time (around 10ms).Therefore:
– Sharing code fragment at different joinpoints
where the same aspects are applicable.
– Preinstalled set of code fragments.
• Partial Evaluation of aspects depending on
dynamic values (e.g. cflow).
• Combination Strategies cached away
unless they implement
jasco.runtime.DoNotCache
JAsCo
6 November 2015 | pag. 48
JAsCo performance
JAC Benchmark
Overhead per joinpoint (μs )
3
2,5
2
1,5
1 aspect @ all methods
24 aspects @ all methods
1 aspect @ 1/8 methods
1
0,5
0
AspectJ 1.1
JAsCo
6 November 2015 | pag. 49
JAsCo 0.4.5
JBoss/AOP
4.0
AspectWerkz
0.9
JAsCo Load-time
Performance
35
Overhead per aspectualized method (ms)
30
25
20
15
10
5
0
AspectJ
JAsCo
6 November 2015 | pag. 50
JAsCo
JBoss/AOP
AspectWerkz
PROSE
JAsCo run-time weaver (1)
Jutta +HotSwap
BASE APP
jp1
Run-time Weaver
BASE APP
jp1
jp2
jp3
jp4
JAsCo
6 November 2015 | pag. 51
jp3
JAsCo run-time weaver (2)
• Performance of JAsCo still slower than
AspectJ
• By combining HotSwap and Jutta, a
genuine run-time weaver can be realized:
aspects inserted into target joinpoints.
• Additional optimizations are possible, e.g.
static or dynamic joinpoint info.
JAsCo
6 November 2015 | pag. 52
Performance of run-time
weaver
AWBench Results
JAsCo
6 November 2015 | pag. 53
TOOL SUPPORT
JAsCo implementations
• JAsCo for Java
• Eclipse plugin IDE
• JAsCoME (J1ME or J2ME compliant
devices)
• JAsCo.NET (technology proof of concept)
JAsCo
6 November 2015 | pag. 55
More Info
• Website:
– http://ssel.vub.ac.be/jasco
• Useful Links:
– thisJoinPoint API:
• http://ssel.vub.ac.be/jasco/nightly/doc/jasco/runti
me/MethodJoinpoint.html
– JAsCo language reference (included in
Eclipse plugin)
JAsCo
6 November 2015 | pag. 56