Tissage dans la programmation orientée aspect
Le tissage est l'étape de la programmation orientée aspect qui a pour but d'insérer des bouts de codes appelés greffons (Advice) dans le code métier d'une application. Tisser un greffon dans une méthode revient à redéfinir la méthode comme la composition de son corps avec le greffon[1]. Le tissage d'aspects au niveau de l'application est un mécanisme offrant l'extensibilité et l'adaptabilité, permettant ainsi à l'application de s'adapter facilement quand des nouveaux besoins font surface[2].
Tisser un aspect peut se faire à plusieurs moments : à la compilation, au chargement et à l'exécution. Il existe de nombreux tisseurs dans différents langages mais c'est en Java que l'on trouve les tisseurs les plus matures (utilisabilité, stabilité, performances, intégration aux outils...).
DĂ©finitions & Rappels
- Aspect
- Un aspect est une entité logicielle qui capture une fonctionnalité transversale à une application[3]. C'est généralement un ensemble de greffons et de points de coupe d'un logiciel.
- Greffon (advice)
- C'est un bloc de code définissant le comportement d'un aspect[4]. Ce bloc de code est destiné à être exécuté au niveau d’un point de coupe avant, après ou autour du point de jonction.
- Point coupe
- Une coupe (pointcut) désigne un ensemble de points de jonction[4].
- Point de jonction
- Un point de jonction(join point) est un point dans l'exécution du programme où un ou plusieurs aspects peuvent être ajoutés[4].Endroit où des aspects peuvent être ajoutés (Méthode, constructeur, Exceptions...)
- Join point shadows[5]
- est la projection statique d'un point de jonction, sur le code du programme.
- DĂ©claration inter-type
- C'est moyen par lequel un aspect ajoute des informations comme des nouvelles propriétés, des nouvelles méthodes ou des interfaces à une classe existante, permettant ainsi d'étendre cette dernière.
- Le tissage statique
- s'effectue à la compilation ou au chargement. Une fois un aspect tissé, il est impossible de le retirer. Lors ce tissage, le code aspect est fusionné avec le code métier[6] - [7]:
- soit pour donner un nouveau code source.
- soit pour donner un pseudo-code intermédiaire.
- Le tissage dynamique[8]
- permet de garder les aspects et le code applicatif complètement séparés. Ainsi, l'exécution, les aspects peuvent être tissés, donc ajoutés au code ou retirés. Cela accroît l’intérêt porté sur la POA pour le prototypage et le test rapides, car on n'a plus besoin de ré-compiler, redéployer et relancer l'application.
Tissage
Le tissage classique basé sur les ombres de point de jointures (join point shadows) comme emplacement de tissage a un problème:efficacité de compilation. Le tissage basé sur les enveloppes[9] vise à diminuer le nombre des emplacements de tissage et par conséquent, la surcharge du au tissage, en introduisant des accesseurs(getter et setter) pour les champs et des proxys pour les méthodes de classes. L'intérêt de cette technique est à trois niveaux. Premièrement, la simplification de la recherche des emplacements de tissage, ceux-ci sont placés dans les enveloppes. Deuxièmement, la diminution du nombre des actions de tissage, car un aspect est tissé une seule fois par champs affecté et troisièmement, simplification du processus de tissage, car on ne se préoccupe plus de maintenir le contrôle de structure des méthodes affectées par le tissage. Grâce à la compilation à temps (just in time), l’indirection introduite par cette technique à un impact faible sur la performance lors de l'exécution. Elle est un complément au tissage statique classique et bien adaptée pour la phase “compilation-teste-debogage”.
Tissage Ă la compilation
Le tissage à la compilation est le plus simple. Il consiste, à prendre le code applicatif et les aspects en entrée et de produire un code mélangé apportant les nouvelles fonctionnalités. Pour ce faire, une étape de pré compilation est nécessaire ou alors, un tisseur est couplé au compilateur. Cette approche produit un code qui demandera moins de contrôles à l'exécution du fait du travail accompli par le compilateur. Ce tissage est obligatoire si les aspects ajoutent des informations nécessaire à la compilation des classes comme de nouveaux champs ou nouvelles méthodes.
Tissage au chargement
Ajouter des nouvelles fonctionnalités aux composants existants sous format binaire se fait par instrumentation du code. Ainsi le tissage se fait au moment où le chargeur de classes charge le code dans la machine virtuel Java (JVM).
Tissage à l'exécution
Cette approche permet de changer le comportement du programme à l'exécution. Pour y parvenir, le support de tissage et d'exécution des aspects est placé directement dans l’environnement d'exécution. L'environnement d'exécution[8], comme la JVM adapté aspects, fournit une interface pour le tissage des aspects pendant l'exécution permettant de changer le modèle d'exécution d'une application.
Tisseurs
Un élément central de la POA est le tisseur. Étant donné un ensemble de programmes ciblés et un ensemble d'aspects définis, le tisseur transforme le programme cible à tisser en un programme enrichi par ces aspects selon certaines contraintes[10]. Il existe plusieurs tisseurs en java. Nous allons considérer ici, les tisseurs les plus connus.
AspectJ
AspectJ[11] est le framework orienté aspect le plus connu. Son mode tissage était purement statique avant sa fusion avec AspectWerkz[12] - [13]en . Cette fusion a permis à AspectJ de faire du tissage dynamique, mais au chargement seulement, et de se doter des annotions dans la mise en œuvre des aspects.
À la compilation, le compilateur AspectJ appelé ajc prend en entrée le code aspect et le code métier et produit en sortie un byte-code tissé. Il est aussi capable de faire de la post-compilation en tissant des aspects dans les fichiers de classe compilés ou dans les fichiers JAR. Ce compilateur est divisé en deux parties, une partie front-end et une back-end[14]. Le front-end, est cette partie qui reçoit en entrée le code aspects et le code métier et qui produit un byte-code annoté avec les informations représentants tout ce qui n'est pas du java pur comme les greffons et les points de coupe. Le back-end quant à lui prend ce byte code annoté et implémente les transformations basées sur ces informations et produit les fichiers de classes tissés. Ces transformations consistent à instrumenter le code en insérant les appels aux méthodes de greffons déjà précompilés.
Pour faire le tissage au chargement, AspectJ utilise un agent de chargement et une configuration fourni sous fichier xml. Cet agent est un chargeur de classe spécial permet d'intervenir au niveau du byte-code. L'agent enrichit donc le code de la classe avec le code d'aspects, pendant le chargement de la classe dans la JVM.
JBoss
JBoss[15] offre un service, nommé JBoss AOP, afin d'utiliser les concepts de l'AOP. C'est une équipe dirigé par Bill Bruke qui est à l'origine du framework, ces droits furent rachetés en 2004 par Red Hat. Avec Jboss AOP il y a deux façons de créer des greffons
- en utilisant un ensemble d'aspect prédéfinis, mais certains ne peuvent d'être utilisé qu'avec JBoss Application Server.
- en les créant.
Les aspects avec JBoss AOP, sont écrits en Java pur sans extension syntaxique mais nécessite l'utilisation d'une API propre à JBoss AOP. Un aspect se compose obligatoirement de deux fichiers :
- le premier contient le code du greffon, appelé intercepteur en JBoss
- le deuxième est un fichier xml. Ce fichier permet de configurer les coupes et d'assurer le déploiement à chaud des aspects au cours de l'exécution.
Avec JBoss AOP le tissage peut ĂŞtre :
- statique : pour cela il faut déclarer lier l'intercepteur et le point de jonction en utilisant la balise
<bind>
- dynamique : en utilisant la balise
<prepare>
mais avant cela il faut configurer la Machine Virtuelle Java pour supporter l'échange à chaud(HotSwapping). L'activation du HotSwap permet d'instrumenter le bytecode des intercepteurs durant l'exécution[16].
Spring
Spring[17] propose un framework, nommé Spring AOP[18], permettant d'utiliser les concepts de la POA. Cependant, le support de la POA proposé par Spring est plus limité que celui d’AspectJ en termes de points de jonction pour définir les coupes, mais Spring à la capacité d'utiliser les aspects développé en AspectJ.
Avec Spring, les greffons sont implémentés sous forme d'une classe java implémentant une certaine interface, selon le type de greffon voulu, sa déclaration se fait à l'aide d'un bean dans le fichier de configuration. Dans ce fichier il faut déclarer également un bean pour spécifier le point de coupe et un autre pour lier le greffon au point de coupe. La portée des aspects est limitée avec Spring, seules les classes définies sous forme de bean peuvent être interceptées.
Il existe trois façons pour définir un point de coupe en Spring AOP:
- avec le nom des méthodes à intercepter.
- avec des expressions régulières pour désigner les méthodes à intercepter.
- avec AspectJ.
Avec Spring AOP, de base les aspects sont tissés au chargement qui se réfère au processus de tissage d'AspectJ, le tissage s'effectue à l'aide de la création dynamique de proxy pour les beans dont les méthodes doivent être interceptées. La génération de ces proxy se fait dans le fichier de configuration. Mais on peut également modifier les greffons pendant l'exécution du programme en paramétrant le fichier de configuration.
JAC
JAC[19] - [20] (Java Aspect Components) est un framework de POA et non un nouveau langage dans lequel la notion de centrale est le composant aspect. Il offre deux niveaux de POA permettant soit de programmer totalement de nouveaux aspects soit de configurer les aspects préprogrammés pour les adapter aux besoins. Un point de coupe est composé de quatre expressions de correspondance à savoir objets, classes, méthodes et hébergeurs. Pour développer un composant aspect, il faut définir des points de coupe et les associer aux méthodes d’encapsulations définies dans les classes adaptateurs Wrapper.
Avec JAC on peut aussi configurer les aspects, en associant à chaque composant aspect un fichier texte décrivant le configuration. Pour effectuer le tissage à l'exécution, le tisseur doit faire une réflexion sur le code métier pour décider si une méthode ou une propriété doit être encapsulé ou pas. Ces décisions sont prises en se basant sur les définitions des points de coupe. Pour y parvenir, un ensemble d’informations sur le code métier sont sauvegardées en mémoire et construites lors du chargement de l’application. Les adaptateurs dynamiques reposent sur le Protocole à méta-objets, permettant d’insérer des crochets dans les adaptateurs lors du chargement. Ces crochets sont des invocations de réflexion qui permettent à la méthode encapsulée être résolue lors de l'exécution. Ainsi un API permettant d’avoir des informations de type à l'exécution peut les accéder.
Contrairement à AspectJ qui traite les aspects au niveau des classes, les instances d'une même classe dans JAC peuvent être modifiées différemment[21]. Grâce aux quatre expressions composant le point de coupe, la granularité est au niveau de l'objet.
Comparaison
Nous allons comparer les tisseurs vus ci-haut, en fonction de leur mise œuvre des aspects. Nous verrons la syntaxe, les points de coupe et les primitives associées et en fin, nous considérons leurs type de tissage et les fonctionnalités offertes.
Syntaxe des aspects
La syntaxe est l'un des critères qui nous permet d'établir les différences et les similarités entre ces différents environnements. Avant de tisser ces aspects, il faut d'abord les écrire.
DĂ©claration Aspect | DĂ©claration Inter-type | Greffon | Point de coupe | Configuration | |
---|---|---|---|---|---|
AspectJ | code aspectJ, annotation, ou XML | code aspectJ, annotation | aop.xml | ||
JAC | code java | fichier texte .acc | |||
JBossAOP | code java + XML | annotation ou XML | code java | statique(fichier XML) ou dynamique (API) | jboss-aop.xml |
SpringAOP | Donnée | Donnée | Donnée | springconfig.xml |
Il convient de noter qu'AspectJ utilise le fichier XML seulement pour le faire le tissage au chargement. JAC de son côté utilise un fichier texte .acc par classe pour effecteur
Points de coupe, points de jonction et primitives associées
Les points de coupe sont très importants pour l'étape de tissage, car ils définissent les endroits dans le code métiers où il faut insérer du code aspects. Les points de jonction représentent les endroits exacte dans le flux d'exécution où le greffon est appelé. Les tisseurs fournissent différentes primitives pour faire des correspondances(matching).
- initialisation : points Ă l'initialisation des classes et des objets
- invocation : points où les méthodes et autres éléments de code sont appelés ou exécutés
- gestions des exceptions: points où les exceptions et les erreurs sont manipulées
Points de jonction | Points de coupe | |||||||
---|---|---|---|---|---|---|---|---|
Initialisation | Invocation | Gestion des exceptions | ContrĂ´le du flux | Matching de point de coupe | Composition de point de coupe | Forme des greffons | Contexte dynamique | |
AspectJ | instanciation, statique, préinitialisation | {méthode, constructeur, greffon} x {appel, exécution} | gestionnaire (handler) | cflow, cflowbelow | signature, type de pattern, sous-type, joker, annotation | &&, !,|| | before, after, after running, after throwing, around | this, target, args, |
JAC | instanciation | exécution des méthodes, exécution des constructeurs | gestionnaire | ? | expression régulière(expression x (objet, classe, méthode)) | type around | par reflexion (RTTI:run time type information) | |
JBossAOP | instanciation | {méthode, constructeur, greffon} x {appel, exécution} | via greffon (advice) | signature, instanceof, joker, annotation | &&, !,|| | around | par accès reflective | |
SpringAOP | instanciation | exécution des méthodes | cflow | expression régulière | && | before, after, returning, around, throws |
Contrairement à AspectJ qui définit cinq types de greffon (before, after, after running, after throwing, around), il n'y a qu'un seul type de wrapper en JAC: around. En effet ce type est plus général et recouvre tous les autres [22]
Type de tissage et fonctionnalites
Compilateur | Tissage | Déploiement | Exécution | |
---|---|---|---|---|
AspectJ | compilateur aspectJ | compilation, chargement | statique | programme java |
JAC | compilateur java | chargement, exécution | dynamique | invocation et gestion par le framework |
JBossAOP | compilateur java, post traitement | compilation, exécution | ||
SpringAOP | compilateur java | chargement, exécution |
Conclusion
Les objets se sont avérés trop petits comme unités de réutilisation et insuffisants pour capturer des préoccupations transversales[23]. De nouveaux paradigmes de programmation comme POA, sont apparus pour compléter la POO. Nous nous sommes donc attardés sur l'une des étapes clés de la POA : le tissage. Qu'il se fasse à la compilation ou au chargement, si un aspect ne peut pas être retiré une fois tissé alors on parle de tissage statique. Si par contre un aspect peut être retiré une fois tissé alors on a affaire au tissage dynamique.
À part les quatre frameworks que nous avons considérés, il y a de nouveaux frameworks qui font aussi de la transformation de code. Spoon[24] permet de faire de l'analyse et la transformation de code source JAVA. Son extension Spoon-AOP a été prouvé capable de faire de la POA de façon flexible, efficace et intuitive, en pur JAVA grâce aux annotations[25].
Références
- Baker, 2002
- Courbis, 2005
- Seinturier, 2005 page 30
- Seinturier, 2005 page 31
- « AOSD »
- « AOP dans les applications java » [archive du ] (consulté le )
- « AOP Concepts et implémentations »
- Popovici, 2002
- Bockish, 2005
- Vasseur, 2004 page 1
- « AspectJ »
- « AspectWerkz 2 » [archive du ] (consulté le )
- Vasseur, 2004
- Hilsdale, 2004
- « JBoss AOP »
- JBoss AOP
- Arnaud Cogoluègnes, Thierry Templier, Julien Dubois et Jean-Philippe Retaillé, SPRING par la pratique, , 117-148 p.
- « Aspect Oriented Programming with Spring »
- « Java Aspect Components »
- Pawlak , 2004
- Pawlak, 2004 page 1122
- Seinturier ,2005 page 41
- Courbis, page 71
- Pawlak, 2005
- Pawlak,2005 page 4
Bibliographie
- (en) Kai Böllert, « On Weaving Aspects », ECOOP Workshops,‎ , p. 301-302 (lire en ligne)
- (en) Lionel Seinturier, « Réflexivité, aspects et composants pour l'ingénierie des intergiciels et des applications reparties », Thèse d'habilitation, Université Pierre et Marie CURIE, Paris VI,‎ (lire en ligne)
- (en) Andrei Popovici, Thomas R. Gross et Gustavo Alonso, « Dynamic weaving for aspect-oriented programming », AOSD '02 Proceedings of the 1st international conference on Aspect-oriented software development,‎ , p. 141–147 (DOI 10.1145/508386.508404)
- (en) Katharina Mehner, Mattia Monga et Gabriele Taentzer, « Analysis of Aspect-Oriented Model Weaving. », Transactions on Aspect-Oriented Software Development V,‎ , p. 235 - 263 (DOI 10.1007/978-3-642-02059-9_7)
- (en) Günter Kniesel, « Detection and Resolution of Weaving Interactions. », Transactions on Aspect-Oriented Software Development V,‎ , p. 135 - 186 (DOI 10.1007/978-3-642-02059-9_5)
- (en) Cristoph Bockish, Michael Haupt, Mira Mezini et Ralf Mitschke, « Envelope-Based Weaving for Faster Aspect Compilers », 6th International Conference on Objects, Components, Architectures, Services, and Applications for a Networked World. AOSD (2005),‎ (lire en ligne)
- (en) Erik Hilsdale et Jim Hugunin, « Advice Weaving in AspectJ », AOSD '04 Proceedings of the 3rd international conference on Aspect-oriented software development,‎ , p. 26-35 (DOI 10.1145/976270.976276)
- (en) Carine Courbis et Anthony Finkelstein, « Towards Aspect Weaving Applications », ICSE '05 Proceedings of the 27th international conference on Software engineering,‎ , p. 69-77 (DOI 10.1145/1062455.1062484).
- (en) Andrei Popovici, Gustavo Alonso et Thomas Gross, « Just-in-time aspects : efficient dynamic weaving for Java. », AOSD '03 Proceedings of the 2nd international conference on Aspect-oriented software development,‎ , p. 100 - 109 (DOI 10.1145/643603.643614)
- (en) Jason Baker et Wilson Hsieh, « Runtime aspect weaving through metaprogramming », AOSD '02 Proceedings of the 1st international conference on Aspect-oriented software development,‎ , p. 86 - 95 (DOI 10.1145/508386.508396)
- (en) Renaud Pawlak, Lionel Seinturier, Laurence Duchien, Gérard Florin et Fabrice Legond-Aubry, « JAC: an aspect-based distributed dynamic framework », DOI: 10.1002/spe.605,‎ , p. 1119–1148 (lire en ligne)
- (en) Renaud Pawlak, « Spoon: Annotation-Driven Program Transformation ― the AOP Case », AOMD '05 Proceedings of the 1st workshop on Aspect oriented middleware development,‎ (DOI 10.1145/1101560.1101566)
- (en) Monia Loulou Aloulou, « Approche Formelle pour la spécification, la vérification et le déploiement des politiques de sécurité dynamiques dans les systèmes à base d'agents mobiles », THESE DE DOCTORAT EN CO-TUTELLE, Université de Bordeaux 1,‎ , p. 92-95 (lire en ligne)