View
151
Download
3
Category
Preview:
Citation preview
MotivationAspecio
Summary
Aspecioaspect-oriented programming meets the OSGi service model
Simon Chemouil
Lambdacube
OSGi Community Event, 2016
1 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Aspecio
Aspecio
A Java/OSGi R6+ ’micro-framework’ that brings a mix of
component-oriented and aspect-oriented programming to your
application.
http: // lambdacube. github. io/ aspecio/
2 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
3 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
4 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
The DRY Principle
Do Not Repeat Yourself
Mostly a rule-of-thumb to organize code
Benefits:
Share code / Fix problems once (modularity)
Limit verbosity (readability)
5 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
The DRY Principle
Do Not Repeat Yourself
Mostly a rule-of-thumb to organize code
Benefits:
Share code / Fix problems once (modularity)
Limit verbosity (readability)
5 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
The DRY Principle
Do Not Repeat Yourself
Mostly a rule-of-thumb to organize code
Benefits:
Share code / Fix problems once (modularity)
Limit verbosity (readability)
5 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
The DRY Principle
Do Not Repeat Yourself
Mostly a rule-of-thumb to organize code
Benefits:
Share code / Fix problems once (modularity)
Limit verbosity (readability)
5 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
The DRY Principle
Do Not Repeat Yourself
Mostly a rule-of-thumb to organize code
Benefits:
Share code / Fix problems once (modularity)
Limit verbosity (readability)
5 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Motivation: modularizing implementations
OSGi solves API & service modularity
What about implementations?
6 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Motivation: modularizing implementations
OSGi solves API & service modularity
What about implementations?
6 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
7 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Modularizing implementations
Example
package com. mylibrary .book;
@Component
public final class BookManagerImpl implements BookManager {
@ Reference AccessControl accessControl ;
public Promise <Book > getBook ( String isbn) {
try {
accessControl . ensureAuthorized (...);
/* business code here */
return actuallyGetBookNow (isbn );
} catch ( Exception e) {
return Promises . failed (e);
}
}
}
8 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Modularizing implementations
Example
package com. mylibrary .book;
@Component
public final class BookManagerImpl implements BookManager {
@ EnsureAuthorized
public Promise <Book > getBook ( String isbn) {
/* business code here */
return actuallyGetBookNow (isbn );
}
}
9 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
DRY and modularityDealing with cross-cu�ing concerns
Modularizing implementations
Example
package com. mylibrary .book;
@Component
public final class BookManagerImpl implements BookManager {
@ EnsureAuthorized
@ Measured
public Promise <Book > getBook ( String isbn) {
/* business code here */
return actuallyGetBookNow (isbn );
}
}
10 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
11 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Aspecio
Aspects at injection-time!
No modification of existing bytecode: dynamic proxy injectioninstead
Built with OSGi in mind
Component-framework agnostic ; also works with plain APIs
Minimal proxy overhead
No primitive boxing, pay for what you use
12 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Aspecio
Aspects at injection-time!
No modification of existing bytecode: dynamic proxy injectioninstead
Built with OSGi in mind
Component-framework agnostic ; also works with plain APIs
Minimal proxy overhead
No primitive boxing, pay for what you use
12 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Aspecio
Aspects at injection-time!
No modification of existing bytecode: dynamic proxy injectioninstead
Built with OSGi in mind
Component-framework agnostic ; also works with plain APIs
Minimal proxy overhead
No primitive boxing, pay for what you use
12 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Framework Hooks
Since OSGi r5 (updated in r6)
Weaving Hooks
Ability to alter the bytecode of a class when it is first loaded.Useful for “traditional” aspect frameworks, or bytecodemanipulation frameworks in general.
Service Hooks
Intercept queries to BundleContext#getService, service events,service listeners registration
14 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Framework Hooks
Since OSGi r5 (updated in r6)
Weaving Hooks
Ability to alter the bytecode of a class when it is first loaded.Useful for “traditional” aspect frameworks, or bytecodemanipulation frameworks in general.
Service Hooks
Intercept queries to BundleContext#getService, service events,service listeners registration
14 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Framework Hooks
Since OSGi r5 (updated in r6)
Weaving Hooks
Ability to alter the bytecode of a class when it is first loaded.Useful for “traditional” aspect frameworks, or bytecodemanipulation frameworks in general.
Service Hooks
Intercept queries to BundleContext#getService, service events,service listeners registration
14 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
15 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Applying Aspects
In Aspecio, service implementations decide if they wantaspects
Two service properties:
service.aspect.weave: “I can only be consumed as aservice if that aspect is woven”service.aspect.weave.optional: “I can be consumedanyhow, but if that aspect is available, use it”
Aspects are similar to service interfaces, they represent aconcept, not necessarily a specific implementation
They are implemented with interceptors that are OSGi servicesand may come and go
16 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Applying Aspects
In Aspecio, service implementations decide if they wantaspects
Two service properties:
service.aspect.weave: “I can only be consumed as aservice if that aspect is woven”service.aspect.weave.optional: “I can be consumedanyhow, but if that aspect is available, use it”
Aspects are similar to service interfaces, they represent aconcept, not necessarily a specific implementation
They are implemented with interceptors that are OSGi servicesand may come and go
16 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Applying Aspects
Example
package com. mylibrary .book;
@Component ( properties = { " service . aspect . weave =com. mylibrary .auth. AuthAspect ",
" service . aspect . weave =com. metrics . MetricsAspect " })
public final class BookManagerImpl implements BookManager {
@ EnsureAuthorized
@ Measured
public Promise <Book > getBook ( String isbn) {
/* business code here */
return actuallyGetBookNow (isbn );
}
}
17 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Applying Aspects
Example
package com. mylibrary .book;
@Component
@Weave ( required = { AuthAspect .class , MetricAspect . class })
public final class BookManagerImpl implements BookManager {
@ EnsureAuthorized
@ Measured
public Promise <Book > getBook ( String isbn) {
/* business code here */
return actuallyGetBookNow (isbn );
}
}
18 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Applying Aspects
Example
package com. mylibrary .book;
@Component
@Weave ( required = AuthAspect .class , optional = MetricAspect . class )
public final class BookManagerImpl implements BookManager {
@ EnsureAuthorized
@ Measured
public Promise <Book > getBook ( String isbn) {
/* business code here */
return actuallyGetBookNow (isbn );
}
}
19 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Defining Aspects
Aspects can have any name, but we use classes by convention
to avoid conflicts.
To publish an Aspect, we register an OSGi serviceimplementing Interceptor (or one of its derivatives)
With the String property service.aspect containing thename of the AspectOptionally, it is possible to define the propertyservice.aspect.extraProperties
20 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Defining Aspects
Aspects can have any name, but we use classes by convention
to avoid conflicts.
To publish an Aspect, we register an OSGi serviceimplementing Interceptor (or one of its derivatives)
With the String property service.aspect containing thename of the AspectOptionally, it is possible to define the propertyservice.aspect.extraProperties
20 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Defining Aspects
Example
package com. metrics ;
// Marker interface
public interface MetricAspect {
}
21 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Defining Aspects
Example
package com. metrics ;
@Component
@Aspect ( provides = MetricAspect .class , extraProperties = " measured ")
public final class AnnotatedMetricInterceptorImpl
implements AnnotationInterceptor <Measured > {
@ Reference Metrics metrics ;
public Class <Measured > intercept () { return Measured . class ; }
public Advice onCall ( Measured annotation , CallContext callContext ) {
String methodName = callContext . target . getName () +
"::" + callContext . method . getName ();
Context syncTimer = metrics . timer ( methodName ). time ();
return new AdviceAdapter () {
public int afterPhases () { return Finally . PHASE ; }
public void runFinally () { syncTimer . close (); }
};
}
}
22 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
23 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
A Closer Look At Interceptors
In Aspecio, services providing aspects are called Interceptors
Interceptors always intercept all service methodsWe can narrow it down by matching some annotations
If multiple interceptors provide the same aspect, Aspeciochooses the one with the highest service ranking
If the rankings are equal, the one with the lowest service id isselected
24 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
A Closer Look At Interceptors
In Aspecio, services providing aspects are called Interceptors
Interceptors always intercept all service methodsWe can narrow it down by matching some annotations
If multiple interceptors provide the same aspect, Aspeciochooses the one with the highest service ranking
If the rankings are equal, the one with the lowest service id isselected
24 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Each time a method of the aspect proxy is called, the methods
onCall of the active interceptors are called
The method onCall returns an Advice
Advices tell Aspecio what to do when a proxy method is called
25 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Each time a method of the aspect proxy is called, the methods
onCall of the active interceptors are called
The method onCall returns an Advice
Advices tell Aspecio what to do when a proxy method is called
25 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Optionally request the actual arguments passed to the method,
and alter them;
Skip the call to the original method and return a value. . . or
proceed with the call;
Obtain throwables potentially thrown by the proxied method
and optionally alter them, but not swallow them;
Obtain and alter the return value
All of these for reference types and all primitive types to
prevent boxing!
26 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Optionally request the actual arguments passed to the method,
and alter them;
Skip the call to the original method and return a value. . . or
proceed with the call;
Obtain throwables potentially thrown by the proxied method
and optionally alter them, but not swallow them;
Obtain and alter the return value
All of these for reference types and all primitive types to
prevent boxing!
26 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Optionally request the actual arguments passed to the method,
and alter them;
Skip the call to the original method and return a value. . . or
proceed with the call;
Obtain throwables potentially thrown by the proxied method
and optionally alter them, but not swallow them;
Obtain and alter the return value
All of these for reference types and all primitive types to
prevent boxing!
26 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Optionally request the actual arguments passed to the method,
and alter them;
Skip the call to the original method and return a value. . . or
proceed with the call;
Obtain throwables potentially thrown by the proxied method
and optionally alter them, but not swallow them;
Obtain and alter the return value
All of these for reference types and all primitive types to
prevent boxing!
26 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Advices
Optionally request the actual arguments passed to the method,
and alter them;
Skip the call to the original method and return a value. . . or
proceed with the call;
Obtain throwables potentially thrown by the proxied method
and optionally alter them, but not swallow them;
Obtain and alter the return value
All of these for reference types and all primitive types to
prevent boxing!
26 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Aspecio’s Dynamic Proxies
Aspecio generates proxies with the ASM bytecode generationlibrary
Proxies might generate several classes lazilye.g if arguments are requested, an immutable data class ingenerated for these unboxed arguments, with proper hashCode
and equals definitions.
Proxies generated by Aspecio expose the same binary signatureas the class they proxy
Including generic signature, annotations, etc, so that frameworkrelying on introspection work transparently
28 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Aspecio’s Dynamic Proxies
Aspecio generates proxies with the ASM bytecode generationlibrary
Proxies might generate several classes lazilye.g if arguments are requested, an immutable data class ingenerated for these unboxed arguments, with proper hashCode
and equals definitions.
Proxies generated by Aspecio expose the same binary signatureas the class they proxy
Including generic signature, annotations, etc, so that frameworkrelying on introspection work transparently
28 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Proxies and Services
Aspecio can proxy services implementing multiple serviceinterfaces just fine
However Aspecio will ignore services registered as a class or anabstract class
Service proxies registered by Aspecio share the same properties
as the woven service
Aspecio handles di�erent service scopes intelligently (includingprototype)
It will not generate di�erent proxies for a singleton servicescoped as bundle for lazy-loading reasons (e.g, by DeclarativeServices)
29 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Proxies and Services
Aspecio can proxy services implementing multiple serviceinterfaces just fine
However Aspecio will ignore services registered as a class or anabstract class
Service proxies registered by Aspecio share the same properties
as the woven service
Aspecio handles di�erent service scopes intelligently (includingprototype)
It will not generate di�erent proxies for a singleton servicescoped as bundle for lazy-loading reasons (e.g, by DeclarativeServices)
29 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Proxies and Services
Aspecio can proxy services implementing multiple serviceinterfaces just fine
However Aspecio will ignore services registered as a class or anabstract class
Service proxies registered by Aspecio share the same properties
as the woven service
Aspecio handles di�erent service scopes intelligently (includingprototype)
It will not generate di�erent proxies for a singleton servicescoped as bundle for lazy-loading reasons (e.g, by DeclarativeServices)
29 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Outline
1 Motivation
DRY and modularity
Dealing with cross-cu�ing concerns
2 Aspecio
Overview
Using Aspecio
Interceptors, Advices and Proxies
Ge�ing started
3 Summary
30 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Ge�ing started
Aspecio is just one bundle
depends only ony an OSGi R6+ frameworkslf4j is an optional dependency; otherwise JUL logging is used
It has to be started early in the framework, before any bundlethat uses it
No way to “fake” service events to “unwire” components;Same situation for all frameworks making use of frameworkhooks, e.g subsystems
31 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Ge�ing started
Aspecio is just one bundle
depends only ony an OSGi R6+ frameworkslf4j is an optional dependency; otherwise JUL logging is used
It has to be started early in the framework, before any bundlethat uses it
No way to “fake” service events to “unwire” components;Same situation for all frameworks making use of frameworkhooks, e.g subsystems
31 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
OverviewUsing AspecioInterceptors, Advices and ProxiesGe�ing started
Checking if Aspecio sees your aspects
Aspecio provides two Gogo commands
aspect:aspects
aspects and interceptors available
aspect:woven
services currently woven, with which aspect
32 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Aspecio Tech Sheet
A bit of a component framework
Plays with service dynamics and registers some on behalf ofother bundles
A lot of bytecode trickery
Mimicking the signature of classes and methods it proxiesSupporting all primitive types for call performance
And a Java DSL to define advices
Advices are close to automata that determine how thegenerated code will interact with user code
33 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Aspecio Tech Sheet
A bit of a component framework
Plays with service dynamics and registers some on behalf ofother bundles
A lot of bytecode trickery
Mimicking the signature of classes and methods it proxiesSupporting all primitive types for call performance
And a Java DSL to define advices
Advices are close to automata that determine how thegenerated code will interact with user code
33 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Aspecio Tech Sheet
A bit of a component framework
Plays with service dynamics and registers some on behalf ofother bundles
A lot of bytecode trickery
Mimicking the signature of classes and methods it proxiesSupporting all primitive types for call performance
And a Java DSL to define advices
Advices are close to automata that determine how thegenerated code will interact with user code
33 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
In-house Feedback
Used on a large project (hundreds of bundles, thousands ofservices)
Easy to get started
Some aspects are extremely useful
Metrics, Access Control, Exception Logging, . . .Practical with integration testing (with and without Aspecio)
Potential improvements:
Be�er stacking of advices, asynchronous support, “this”handling
34 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
In-house Feedback
Used on a large project (hundreds of bundles, thousands ofservices)
Easy to get started
Some aspects are extremely useful
Metrics, Access Control, Exception Logging, . . .Practical with integration testing (with and without Aspecio)
Potential improvements:
Be�er stacking of advices, asynchronous support, “this”handling
34 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
In-house Feedback
Used on a large project (hundreds of bundles, thousands ofservices)
Easy to get started
Some aspects are extremely useful
Metrics, Access Control, Exception Logging, . . .Practical with integration testing (with and without Aspecio)
Potential improvements:
Be�er stacking of advices, asynchronous support, “this”handling
34 / 35 Simon Chemouil Aspecio
MotivationAspecio
Summary
Aspecio
�estions?
http: // lambdacube. github. io/ aspecio/
Twi�er:
@simach
simon.chemouil@lambdacube.fr
35 / 35 Simon Chemouil Aspecio
Recommended