aspecio - aspect-oriented programming meets the osgi service model - simon chemouil

61
Motivation Aspecio Summary Aspecio aspect-oriented programming meets the OSGi service model Simon Chemouil Lambdacube OSGi Community Event, 2016 1 / 35 Simon Chemouil Aspecio

Upload: mfrancis

Post on 16-Apr-2017

151 views

Category:

Technology


3 download

TRANSCRIPT

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

The Big Picture

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

The Big Picture Again

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

[email protected]

35 / 35 Simon Chemouil Aspecio

Evaluate the Sessions

Sign in and vote at eclipsecon.org

- 1 + 10