• Nenhum resultado encontrado

Structuring Adaptive Applications using AspectJ

N/A
N/A
Protected

Academic year: 2021

Share "Structuring Adaptive Applications using AspectJ"

Copied!
132
0
0

Texto

(1)%. & & &( )*. ). !. & ' % +. "##$.

(2) UNIVERSIDADE FEDERAL DE PERNAMBUCO ´ CENTRO DE INFORMATICA. Ayla D´ebora Dantas de Souza. Structuring Adaptive Applications using AspectJ. Este trabalho foi apresentado `a P´os-gradua¸ca˜o em Ciˆencia da Computa¸ca˜o do Centro de Inform´ atica da Universidade Federal de Pernambuco como requisito para a conclus˜ ao do mestrado na mesma.. ORIENTADOR: Prof. Paulo Henrique Monteiro Borba. ii.

(3)

(4) Agradecimentos Primeiramente a Deus, porque sem ele nada na vida teria sentido e com certeza eu n˜ao ´ certamente a Ele que eu agrade¸co pela for¸ca para suportar teria chegado at´e aqui. E a distˆ ancia de muitas pessoas que eu amo muito e para continuar, mesmo quando o cansa¸co queria tomar conta de mim. Aos meus pais e irm˜ as, pelo imenso carinho, pela compreens˜ ao devida a minha ausˆencia e por terem sido meus grandes incentivadores, desde os meus primeiros passos. A Rodrigo, por ao mesmo tempo ter sido o namorado, o amigo companheiro, o conselheiro e o colega com quem podia compartilhar id´eias sobre o meu trabalho de mestrado e o estresse resultante deste. A Paulo Borba, por confiar no meu trabalho, incentivando-me em alguns momentos de desˆ animo, e por ter me ensinado tanto, ao longo desses dois anos, sendo um verdadeiro exemplo de orientador. Ele realmente sabe fazer gerenciamento de threads... A Joe Yoder, por mesmo de t˜ao longe, ter dado tantas contribui¸co˜es ao meu trabalho, em especial no padr˜ ao e no que se referia a AOM, e por ter se mostrado um verdadeiro amigo. A Ralph Jonhnson, pela sua aten¸ca˜o e pelas cr´ıticas construtivas relativas ao Cap´ıtulo 6. A Paulo Masiero, pelas contribui¸co˜es dadas ao nosso padr˜ ao, sendo nosso shepherd no SugarLoafPLoP. Aos professores Markus Endler e Andr´e Santos, por examinarem essa disserta¸ca˜o e por suas interessantes sugest˜ oes de melhoria. A Rohit, Vander, Tiago, S´ergio e Leonardo, meus colegas do SPG, pelas id´eias trocadas, textos revisados, boas risadas compartilhadas e pela sua valiosa amizade. ` minhas companheiras de apartamento, Ellen e Ge´orgia, e a Adjamir, pelos As in´ umeros momentos compartilhados, e por me fazerem sentir em um lar, mesmo quando est´ avamos afastados dos nossos. A todos os amigos que fiz em Recife (no CIn, no CESAR ou no Inocoop) e tamb´em aos que ficaram em Campina, por terem me proporcionado tantos momentos felizes, que me traziam motiva¸ca˜o para o trabalho. A Rohit e Franklin, por me terem cedido tantas caronas a nossa terrinha, tendo sempre paciˆencia quando eu sentia mal estar durante a viagem e por terem sido verdadeiros irm˜ aos. A minha amiga J´ ulia, por revisar algumas partes dessa disserta¸ca˜o. Ao Centro de Inform´ atica, pelo suporte t´ecnico e acadˆemico durante esses dois anos, e ao Departamento de Sistemas e Computa¸ca˜o, pela base obtida em minha gradua¸ca˜o. Enfim, muito obrigada a todos os que apostaram e torceram por mim.. iv.

(5) Resumo Os dispositivos computacionais est˜ ao se tornando ub´ıquos. Com um celular, atualmente, podemos acessar e manipular informa¸ca˜o praticamente em qualquer lugar e a qualquer instante. Neste cen´ ario de computa¸ca˜o ub´ıqua, tem-se exigido que tais sistemas sejam adaptativos, ou seja, tenham a capacidade de se adaptar em decorrˆencia de mudan¸cas no contexto em que est˜ ao inseridos. ´ E importante destacar, por´em, que a adaptabilidade adiciona certa complexidade ao desenvolvimento de aplica¸co˜es. Um dos problemas ´e que a implementa¸ca˜o de comportamentos adaptativos em muitos casos se entrela¸ca com outras preocupa¸co˜es da aplica¸ca˜o, como apresenta¸ca˜o, neg´ ocio e dados, levando a problemas de legibilidade que podem prejudicar a manutenabilidade do c´odigo. A programa¸ca˜o orientada a aspectos pode ser usada para facilitar a resolu¸ca˜o de problemas relacionados a c´odigo entrela¸cado, e dar suporte ao desenvolvimento de programas adaptativos, e ao mesmo tempo adapt´ aveis (f´aceis de modificar) com bons n´ıveis de qualidade e produtividade. Essa disserta¸ca˜o mostra como podemos usar aspectos, em especial em AspectJ, para estruturar aplica¸co˜es adaptativas, minimizando dessa forma o entrela¸camento de c´odigo. AspectJ ´e uma linguagem orientada a aspectos, de prop´ osito geral, e que estende a linguagem Java. Ela ´e voltada `a separa¸ca˜o de preocupa¸co˜es. Em nosso trabalho ela ´e utilizada para promover a separa¸ca˜o da preocupa¸ca˜o “adaptabilidade”, obtendo-se assim uma implementa¸ca˜o modular. Atrav´es do uso dessa linguagem, identificamos boas pr´aticas para a estrutura¸ca˜o de aplica¸co˜es adaptativas, as quais foram resumidas em um padr˜ ao denominado Adaptability Aspects. Escolhemos a plataforma Java 2 Micro Edition para implementar v´ arias preocupa¸co˜es relativas a adaptabilidade, principalmente pelo fato de ser uma tecnologia destinada a dispositivos ub´ıquos e com recursos limitados. Al´em de AspectJ, analisamos tamb´em uma outra abordagem para a estrutura¸ca˜o de aplica¸co˜es adaptativas: o uso do estilo arquitetural denominado “Adaptive ObjectModels”. Verificamos a partir dessa an´alise que ele poderia ser combinado com o nosso padr˜ ao, e portanto, beneficiar-se com o uso de aspectos. Dessa forma, poderia-se oferecer suporte a um conjunto maior de adapta¸co˜es e ao mesmo tempo obter-se uma estrutura¸ca˜o no c´odigo mais f´acil de compreender. Por fim, avaliamos o impacto de AspectJ, atrav´es do uso do padr˜ ao Adaptability Aspects, para implementar alguns requisitos de adaptabilidade em aplica¸co˜es J2ME. Comparamos nossa implementa¸ca˜o com uma solu¸ca˜o em que a implementa¸ca˜o destes requisitos n˜ao ´e t˜ao modular e com uma outra solu¸ca˜o utilizando padr˜ oes de projeto puramente orientados a objeto na qual se buscava tal modularidade. Alguns dos aspectos comparados foram tempo de execu¸ca˜o, mem´oria utilizada, tamanho da aplica¸ca˜o e de seu c´odigo. Al´em de medir tais fatores, descrevemos os ganhos que a programa¸ca˜o orientada a aspectos pode trazer para a estrutura¸ca˜o de aplica¸co˜es adaptativas visando obter qualidade em termos de reuso e facilidade de manuten¸ca˜o. Palavras chave: adaptabilidade, sistemas adaptativos, padr˜ oes, Adaptive-Object Models, separa¸ca˜o de preocupa¸co˜es, programa¸ca˜o orientada a aspectos, AspectJ, evolu¸ca˜o de software.. v.

(6) Abstract Computational devices are becoming ubiquitous. Nowadays, with devices such as cellular phones, we can access and manipulate information at anytime, stored anywhere. In this ubiquitous computing scenario, it is common to require from these systems the ability to adapt as a response to changes in their operating environment, being therefore adaptive. However, adaptability often increases the complexity of the development process. One of the problems is that the implementation of adaptive behavior is in many cases tangled with other application concerns, such as GUI, business logic and data manipulation code. This code tangling can lead to understandability and maintainability problems. Aspect-oriented programming can help address the code tangling problem and support the development of adaptive and also adaptable (easy to modify) software, with adequate productivity and quality levels. This dissertation shows how we can use aspects, in particular AspectJ, for structuring adaptive applications, thus minimizing code tangling. AspectJ is a general-purpose aspect-oriented extension to Java developed to provide separation of concerns. In this work, it is used to separate the “adaptability” concern, leading to a more modular design. By using this language, we have identified some good practices for structuring adaptive applications, which were summarized in an architectural pattern called Adaptability Aspects. We chose the Java 2 Micro Edition as our platform to implement several adaptive concerns, primarily because it is targeted to ubiquitous and resource-constrained devices. We have also analyzed another approach for structuring adaptive applications, namely the “Adaptive Object-Model” architectural style. We show how this architectural style can be combined with our pattern, and therefore benefit from the advantages provided by aspects. Consequently, the enhanced AOM systems provide support for more kinds of adaptive behavior, presenting a more understandable code structure, which can improve maintainability. Finally, we evaluate AspectJ for implementing some adaptive requirements in J2ME applications following the Adaptability Aspects pattern. This evaluation compares an implementation using aspects with a pure Object-Oriented solution using GoF patterns, and with a less flexible implementation where the adaptability concerns are not so well isolated. Some of the measures taken were execution time, memory use, application and its code size. Besides measuring these elements, we have also described the gains of aspect-oriented programming for structuring adaptive applications in order to obtain better quality levels in terms of maintainability and reuse.. Keywords: adaptability, adaptive systems, patterns, adaptive object-models, separation of concerns, aspect-oriented programming, AspectJ, software evolution.. vi.

(7) Contents 1 Introduction 1.1 Dissertation Organization . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Adaptive Software 2.1 Adaptability . . . . . . . 2.2 Adaptive Object-Models 2.2.1 The Architectural 2.2.2 AOM patterns . . 2.2.3 AOM Evaluation. . . . . . . . . . . . . . . . . . . Style of AOMs . . . . . . . . . . . . . . . . . .. 3 AspectJ 3.1 Aspect-Oriented Programming . . 3.1.1 Separation of Concerns . . 3.1.2 Aspect-Oriented Paradigm 3.2 AspectJ Overview . . . . . . . . . 3.3 AspectJ Language . . . . . . . . 3.3.1 Join Points and Pointcuts 3.3.2 Advice . . . . . . . . . . . 3.3.3 Inter-type Declarations . . 3.3.4 Aspects . . . . . . . . . . 3.3.5 Types of crosscutting . . . 3.3.6 Program Composition . . 3.3.7 Other Approaches . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . .. . . . . .. 5 . 6 . 7 . 7 . 8 . 10. . . . . . . . . . . . .. 13 14 14 14 16 17 17 19 22 23 24 25 25. . . . . . . . . . . . .. 4 Introducing Adaptive Behaviors with Aspects 4.1 The Dictionary Application . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Developing Adaptive J2ME Applications Using AspectJ . . . . . . . . . . 4.2.1 Evaluation Organization . . . . . . . . . . . . . . . . . . . . . . . 4.2.2 Customization Concern . . . . . . . . . . . . . . . . . . . . . . . . 4.2.3 Screens Concern . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.4 Caching Concern . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.5 Internationalization Concern . . . . . . . . . . . . . . . . . . . . . 4.2.6 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Representing and Retrieving Data for Dynamic Adaptations . . . . . . . 4.3.1 AOMs for Storing and Retrieving Data for Dynamic Adaptations 4.3.2 An AOM Implementation for an Adaptation Data Provider Module. vii. 1 3. 26 27 28 29 30 35 38 39 40 42 43 43.

(8) 4.3.3 4.3.4 4.3.5 5 The 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12. XML Schema for an AOM implementation of the Adaptation Data Provider Module . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Procedure for implementing and using AOM Data Providers with XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Evaluation of the AOM Adaptation Data Provider . . . . . . . . 53. Adaptability Aspects Pattern Intent . . . . . . . . . . . . . . . Context . . . . . . . . . . . . . . Problem . . . . . . . . . . . . . . Forces . . . . . . . . . . . . . . . Solution . . . . . . . . . . . . . . Structure . . . . . . . . . . . . . Dynamics . . . . . . . . . . . . . Consequences . . . . . . . . . . . Implementation . . . . . . . . . . Example . . . . . . . . . . . . . . Known Uses . . . . . . . . . . . . See Also . . . . . . . . . . . . . .. . . . . . . . . . . . .. 55 56 56 56 56 57 57 59 60 62 64 67 68. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AOM . . . . . . . .. 70 71 72 72 72 74 79 80 80 82 85 86. . . . . . . . .. . . . . . . . .. 88 89 89 90 91 92 94 94 96. 8 Conclusions and Future Work 8.1 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 98 99 100 106. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. 6 Using Aspects to Make Adaptive Object-Models Adaptable 6.1 Advantages and Drawbacks of AOM . . . . . . . . . . . . . . . . 6.2 Introducing Adaptive Behaviors with AOM . . . . . . . . . . . . . 6.2.1 The Dictionary Application Modified . . . . . . . . . . . . 6.2.2 Adaptive Behaviors . . . . . . . . . . . . . . . . . . . . . . 6.2.3 Implementing Adaptability with AOM . . . . . . . . . . . 6.3 Using AOP to improve AOMs . . . . . . . . . . . . . . . . . . . . 6.3.1 The Adaptability Aspects Pattern Essence . . . . . . . . . . 6.3.2 The DynamicProperties Aspect . . . . . . . . . . . . . . 6.3.3 Implementing Other Adaptability Concerns with AOP and 6.3.4 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4 Chapter Summary . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Adaptability Aspects Evaluation 7.1 Comparative Study Organization . . . 7.1.1 Application Versions . . . . . . 7.1.2 Some Experiment Concepts and 7.1.3 Environment Settings . . . . . . 7.2 Data Analysis . . . . . . . . . . . . . . 7.3 Study Conclusions . . . . . . . . . . . 7.4 Comparing with TangSol . . . . . . . . 7.5 Other Qualitative Results . . . . . . .. viii. . . . . . . their . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . Correspondents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . .. . . . . . . . .. . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . .. . . . . . . . . . . . .. . . . . . . . ..

(9) A Procedure for Deploying a J2ME Application using AspectJ. 108. B T-Test Procedure and Results. 109. ix.

(10) List of Figures 2.1 2.2 2.3 2.4 2.5. TypeObject example . . . . . . . . Implementing the Property pattern TypeSquare . . . . . . . . . . . . . TypeSquare with Rules . . . . . . . Storing and Retrieving Metadata .. 3.1 3.2 3.3. Figure Editor Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Before advice example using Eclipse IDE for AspectJ . . . . . . . . . . . 20 Aspect members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9. Dictionary application UML model . . . . . . . . . . . Customization concern implementation in AspectJ . . . Customization concern purely OO implementation . . . Screens Concern implementation using AspectJ . . . . Caching aspect relation with other aspects . . . . . . . Adaptation Data Provider Implementation with AOM . AOM Schema Graphical Representation . . . . . . . . Object-model for internationalization . . . . . . . . . . Auxiliary class for Internationalization . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. . . . . . . . . .. 28 30 34 36 38 44 45 48 51. 5.1 5.2 5.3 5.4 5.5 5.6. Adaptability Aspects elements. . . . . . . . . . . . . . . . . Dynamics of Adaptability Aspects pattern (scenario I) . . . Dynamics of the Adaptability Aspects pattern (scenario II) Context Manager Possible Implementation . . . . . . . . . An Adaptability Aspects pattern example . . . . . . . . . . Entity configuration example . . . . . . . . . . . . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. 58 60 61 63 65 68. 6.1 6.2 6.3 6.4 6.5 6.6. Dictionary Screens: Presentation, Main Menu, Instructions, Info and Search Screen respectively . . . . . . . . . . . . . . . . . . . . . . . . . . Dictionary Application without Adaptive Behaviors . . . . . . . . . . . . Property pattern used in the dictionary application . . . . . . . . . . . . Using the Properties, TypeObject and Strategy Pattern on the dictionary Possible objects configuration . . . . . . . . . . . . . . . . . . . . . . . . InfoScreen and UserDataScreen snapshots . . . . . . . . . . . . . . . . .. 73 74 75 76 77 78. 7.1. Percentual Difference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96. x. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . 8 . 9 . 10 . 11 . 11.

(11) List of Tables 3.1 3.2. Pointcut Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 AspectJ Advice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20. 7.1 7.2 7.3 7.4 7.5 7.6 7.7. Hardware and Software Specification . . . . . . . . . . . . . . . Source Code Size . . . . . . . . . . . . . . . . . . . . . . . . . . Deployed Application Size . . . . . . . . . . . . . . . . . . . . . Performance Results . . . . . . . . . . . . . . . . . . . . . . . . Memory Use Results . . . . . . . . . . . . . . . . . . . . . . . . TangSol Results . . . . . . . . . . . . . . . . . . . . . . . . . . . AspSol Percentual Difference in Relation to PatSol and TangSol. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. 91 92 93 93 94 95 95. B.1 B.2 B.3 B.4 B.5 B.6. startApp Method Execution Time for AspSol(a) x PatSol(b) . search Method Execution Time for AspSol(a) x PatSol(b) . . Memory Use for AspSol(a) x PatSol(b) . . . . . . . . . . . . . startApp Method Execution Time for AspSol(a) x TangSol(b) search Method Execution Time for AspSol(a) x TangSol(b) . Memory Use for AspSol(a) x TangSol(b) . . . . . . . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. . . . . . .. 110 111 111 112 112 113. xi. . . . . . ..

(12) Chapter 1 Introduction. In this chapter we discuss the increasing demand for adaptive systems and overview our results on AspectJ’s applicability for the implementation of such systems better isolating the adaptability concern.. 1.

(13) The unrelenting pace of change that confronts contemporary software developers compels them to make their applications more configurable, flexible, and adaptive. Adaptive applications behave differently, according to changes on their operating environment [57], and they have become common, specially in ubiquitous computing, an area of significant interest currently [51]. Implementing this kind of application involves complex issues. Therefore, it is important to provide adaptive behavior considering quality and productivity factors, especially because such applications may be subject to frequent requirements changes. To implement adaptive applications, software designers must provide flexible architectures that can more quickly adapt to changing requirements. Adaptive Object-Model (AOM) [81] is an architectural style intented to provide such flexibility through the interpretation of metadata describing the systems’ structure and behavior. Another possible solution is the use of common design patterns, such as the GoF ones [23]. However, even with AOMs and patterns, the adaptability concern implementation is sometimes tangled with GUI and business logic code1 or its isolation makes the code difficult to understand. This leads to poor maintainability, especially when an adaptive behavior must change, or a new one must be included. The kind of maintenance intended to add new features and change functionalities is known as adaptive maintenance. It is performed in anticipation of change within the data and processing environments [49]. This anticipation refers to architectures prepared to the inclusion of new requirements, for example, making such inclusion easier. When the adaptive behavior refers to reconfiguration of distributed applications, this type of maintenance can be improved through the use of middlewares for adaptive applications [44] or frameworks [66]. However, sometimes we cannot use such approaches, because we have limited devices. We may also only want some programming techniques, because the reconfigurations only affect the application internal structure and we do not need all features provided by a framework or middleware. In these cases, it is necessary to find techniques to avoid common problems in the development of adaptive applications, such as adaptability code scattering, because it is difficult to isolate the “adaptability” concern using pure object-oriented (OO) approaches. Observing these problems in the development of adaptive applications, our main objective is to propose some techniques for structuring them using the AspectJ [38] language, a general-purpose aspect-oriented extension to Java [27]. Although we have focused on this language, some of our results can be generalized to other Aspect-Oriented Programming (AOP) languages and tools, because many ideas used in AspectJ are also explored in other approaches. This dissertation brings the following contributions: • Evaluate AspectJ as a tool to develop adaptive Java applications, especially the ones developed with Java 2 Micro Edition (J2ME) [60], which are targeted to applications domains that have adaptability as a common requirement, identifying advantages and drawbacks. • Propose some ways to organize and retrieve dynamic data that represent the system’s new structure and behavior when an adaptation is triggered. 1. Business logic is the code concerned with the underlying business functionality. In the Model-ViewController framework it corresponds to the model [1].. 2.

(14) • Propose the Adaptability Aspects pattern, an architectural pattern, for structuring adaptive applications using aspects. • Enhance a particular kind of reflective architecture, called Adaptive Object-Model (AOM) architecture [82], through the use of Aspect-Oriented Programming (AOP) for obtaining better maintainability. • Evaluate the impact on the use of aspects, especially through the Adaptability Aspects pattern for implementing adaptive behavior in J2ME applications considering factors such as memory use, execution time, application and code size, reuse and modularization. Some of these results have been published elsewhere [17, 14, 15] and we use a J2ME dictionary application to illustrate the implementation of several adaptive behaviors based on the techniques discussed throughout this dissertation. This work was developed according to the following methodology: • We have chosen the J2ME dictionary application and implemented several adaptive behaviors there using AspectJ. • In order to provide dynamic data for adaptations, we have proposed a module for providing and retrieving this data. • Considering the lessons learned in the implementation of adaptive behaviors in the dictionary and of the adaptation data provider module, we have proposed a pattern for structuring adaptive applications with aspects. • Analyzing the solution proposed by AOM systems, we have proposed a way to improve such solutions with aspects avoiding maintainability problems. • Finally, we have performed an experiment comparing the implementation of the same adaptive requirements using Adaptability Aspects and pure Object-Oriented solutions.. 1.1. Dissertation Organization. The remainder of this dissertation is organized as follows. Chapters 2 and 3 provide the background for better understanding this work. Chapter 2 describes adaptive software and the Adaptive Object-Model architectural style. Chapter 3 presents the AspectOriented Programming paradigm and the AspectJ language. In Chapter 4 we present the problems of some current approaches for implementing adaptive behavior, especially those that crosscut the application functionality and internal structure, evaluating AspectJ use for minimizing these problems. We also present some techniques to represent and retrieve data used for dynamic adaptations. In Chapter 5, we present the Adaptabilily Aspects architectural pattern, intended to structure adaptive applications using aspects. In Chapter 6 we discuss the applicability of AOMs for implementing adaptive systems, some problems this architectural style can present and how aspects can be used to minimize these problems. In Chapter 7 we discuss the implications of using AspectJ 3.

(15) through the Adaptabilily Aspects pattern in environments with restricted resources for implementing adaptability. Finally, Chapter 8 concludes this work by summarizing the contributions, indicating related work, and suggesting directions for future research.. 4.

(16) Chapter 2 Adaptive Software. The unrelenting pace of change that confronts contemporary software developers compels them to make their applications more configurable, flexible, and adaptive. This chapter describes such necessity, pointing out some practices for achieving it.. 5.

(17) Adaptability is an important requirement, and this word has been used to refer to adaptive and adaptable software. Sometimes the words adaptive and adaptable are used interchangeably. However, when used together, they can present different meanings. A program is called adaptable if its source code can be easily changed. A program is adaptive if it changes its behavior automatically, during its execution, according to context changes [47]. This chapter describes the need for software that is easy to change in order to adapt to new user requirements, even automatically, and also those that are able to reconfigure themselves in response to changes in their operating environment. It also describes the Adaptive Object-Model Architectural Style [81], which is intended to improve the flexibility of systems by providing a meta-architecture that allows requirements changes to be performed and immediately reflected at runtime.. 2.1. Adaptability. The adaptability requirement has been pointed out as one of the challenges of ubiquitous computing [51], an area of significant interest currently and that also demands flexible and configurable architectures. Adaptability can be defined as the ability to change or be changed to fit varying circumstances. This is a desirable characteristic in distributed and mobile systems too. Some examples of adaptations are new behaviors according to changes in the application’s environment such as user inputs, server responses, hardware temperature, power conditions, device geographic localization, and so forth. Other examples of adaptations are business systems that manage products of some sort and are extended to add new products with their relevant attributes, relationships, and business rules. In the meaning previously presented, adaptability is totally related to self-adaptive, or simply adaptive software, which modifies its own behavior in response to changes in its operating environment [57]. There are many points that must be observed in the development of this kind of software: • The conditions that should trigger an adaptation and how often they should be considered; • The ability to introduce new application behaviors and adaptation plans during runtime; • The type of autonomy to be supported (if fully automatic adaptation or humanin-the-loop); • The cost-benefit of an adaptation ; and • The kind of information to be collected to make adaptation decisions. Besides considering these points, the developer must also be worried about the maintainability of those systems. Providing so much flexibility sometimes leads to code that is difficult to understand. In such cases, we can say this code is not adaptable, specially when the triggered changes affect the application internal structure. In those cases,. 6.

(18) correcting a bug or making adaptive changes is a difficult task. The kind of maintenance intended to add new features and change functionalities is known as adaptive maintenance. It is performed in anticipation of change within the data and processing environments [49]. Many approaches [66, 16] have discussed adaptability from the view point of distributed systems, well exploring aspects such as monitoring and reconfigurability of distributed components. As this work focuses on how to structure adaptive applications, we give more attention to adaptations that may affect the application functionalities and internal organization due to requirements that can come from the user or from the developer. In this direction, we focus on techniques, instead of concrete solutions such as middlewares or frameworks, which can be used even in the development of such solutions. Another approach regarding dynamically adapting applications due to requirements changes is the Adaptive Object-Model architectural style, which is described in Section 2.2.. 2.2. Adaptive Object-Models. This section presents the Adaptive Object-Model (AOM) Architectural style and some related patterns. It is important to notice that systems built using this architectural style are called AOMs too. In the following, we describe the general idea followed by these systems and how they are generally structured.. 2.2.1. The Architectural Style of AOMs. In object-oriented programming, we aim to develop robust and easy to maintain architectures. However, the business rules, although logically independent, are usually part of the executable code of the applications. As a consequence, applications subject to constant and dynamic changes demand a significant codification rework. Adaptive Object-Model [81] systems deal with this problem in a different way, representing the business rules and entities not as code, but as stored data (in database or XML files, for example). An AOM system has two coexisting object systems: the interpreter written in the object-oriented programming language and the Adaptive ObjectModel that is interpreted. This organization makes changes in business rules and entities easier; moreover, those changes can be performed by domain specialists instead of developers, since no programming skills are necessary. The stored data containing classes, attributes, relationships, and the system behavior is called metadata and is interpreted at runtime; this makes this kind of systems very dynamic and easy to adapt to new business needs. Hence, systems conforming to the AOM Architectural Style represent classes, attributes, relationships, and behavior as metadata. These systems implement a model based on instances rather than classes. Users change the metadata (object model) to reflect changes in the domain. Consequently, the object model is adaptive; when the descriptive information is modified, the system immediately reflects those changes [82].. 7.

(19) 2.2.2. AOM patterns. AOM architectures are usually made up of several smaller design patterns, such as the Composite, Interpreter, Builder, and Strategy [23], along with other dynamic patterns such as TypeObject [37], Property [21], and RuleObjects [3, 4]. Most AOM architectures apply the TypeObject and Property patterns together, which results in an architecture called TypeSquare [81]. Using such patterns, we can represent application features, attributes and rules (or strategies) as metadata that can be interpreted in a running system. Since classes, attributes and relationships (which can be a kind of property) are represented as metadata in AOM systems, we can say these systems have an underlying model based on instances. Changes in this metadata can be easily performed and the system may immediately reflect them. In the following, we describe some of these patterns. TypeObject The TypeObject [37] pattern provides a way to dynamically define new business entities for the system. Object-oriented systems generally use a separate class for each kind of object, so introducing a new kind of object requires making a new class, which requires programming. TypeObject makes the unknown subclasses simple instances of a generic class, as the Car example, illustrated by Figure 2.1 shows:. Figure 2.1: TypeObject example. This figure shows an example of how a Car class with a set of subclasses such as Caravan, Camry, and Explorer is transformed into a pair of classes, Car and CarType. These transformed classes represent the class model of the interpreter and are used at runtime to represent the Entities and EntityTypes of the system. Replacing a hierarchy like this is possible when the behavior between the subclasses is very similar or can be broken out into separate objects. In these cases, the primary differences between the subclasses are the values of their attributes. The Entities’ attributes are implemented 8.

(20) with the Property pattern, which is explained in the following. The TypeObject pattern must be used when [37]: • instances of a class need to be grouped together according to their common attributes and/or behavior. • the class needs a subclass for each group to implement that group’s common attributes/behavior. • the class requires a large number of subclasses and/or the total variety of subclasses that may be required is unknown. • you want to be able to create new groupings at runtime that were not predicted during design. • you want to be able to change an object’s subclass after it has been instantiated without having to mutate it to a new class. • you want to be able to nest groupings recursively so that a group is itself an item in another group. Property The Property [21] pattern is used to implement the Attributes of each Entity. By using this pattern, instead of each attribute being a different instance variable, we must make an instance variable that holds a collection of attributes. This can be done using a dictionary, vector, or lookup table. Each property of the collection may present the name of the attribute, its type, and its current value. Figure 2.2 illustrates this pattern application on the Car class.. Figure 2.2: Implementing the Property pattern. In most AOM systems, TypeObject is used twice, once before using the Property pattern, in order to provide the relationship between Entities and EntityTypes, and once after it, for providing generic Properties that present a relationship with PropertyTypes. The resultant architecture is called TypeSquare [81], which is illustrated by Figure 2.3.. 9.

(21) Figure 2.3: TypeSquare. Strategies and Rule Objects The Strategy [23] and RuleObject [3, 4] patterns are used to provide AOM systems a way to describe and change the behavior of EntityTypes by handling business rules [82]. Some rules may define legal entities in a system along with their attributes and also legal subtypes. Other rules will define the legal types of relationships between entities. However, some rules may be more complex, such as one that states that certain entityrelationships are only legal if the entities have certain values and other constraints are met. A Strategy is an object that represents an algorithm. The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. By using this pattern, the algorithms may vary independently from clients that use them [23]. However, as more elaborate business rules are needed, the Strategies can become more complex. These can be either primitive rules or the combination of business rules through application of the Composite pattern [23]. Rules that represent predicates are composed of conjunctions and disjunctions, rules that represent numerical values are composed by addition and subtraction rules, rules that represent sets are composed by union and intersection rules . These more complex Strategies are called RuleObjects [82]. Figure 2.4 shows a UML diagram representing the TypeSquare with Rules, which is a common structure in AOM systems.. 2.2.3. AOM Evaluation. The main advantage of AOM systems is ease of change. They can even allow users to configure and extend their systems “without programming” and make the process of changing them quickly. However, there is a higher initial cost in developing this kind of system, because it must be as general as possible in order to improve extensibility and make possible many sorts of adaptations. Generally, these systems are also difficult to understand because several classes do not represent business abstractions; the objectmodel is represented in metadata. However, auxiliary Graphical User Interface (GUI) tools and editors can be used to alleviate this problem. Another problem presented by the AOM architecture is performance, since it is based on the interpretation of metadata. 10.

(22) Figure 2.4: TypeSquare with Rules. Therefore, before deciding to use AOM or not, an analysis of the desired level of adaptability should be performed. This analysis should consider which parts of the system need to be highly adaptive. For instance, if the developed system has to be very flexible, or if the rules or properties of this system might change often, AOM can be a good choice, despite the problems presented above. Figure 2.5 illustrates a possible organization of the AOM systems’ process of storing and retrieving metadata.. Figure 2.5: Storing and Retrieving Metadata. We must note that no matter how the metadata is stored, these systems must be able to read it and populate the Adaptive Object-Model with the correct configuration of instances, including objects which are domain specific (domain objects). By this process we may obtain dynamic systems that easily change because their entities, types, properties and rules representation can be reconfigured without changing the code. The best-known alternatives for AOM architectures or related techniques are Code 11.

(23) Generators, Generative Programming, Metamodeling, and Reflective Techniques [82]. Code generators are different from AOM primarily because AOMs immediately reflect the changed business requirement without any code generation or recompilation. They are related in that the functionality of systems is not directly produced by programmers but specified using domain-related constructs. Generative Programming [9] and Metamodeling approaches are also intended to provide different techniques for giving users the same power AOMs give. Generative Programming provides infrastructure for transforming descriptions of a system into code whereas Metamodeling techniques include a variety of approaches, most of which are generative in nature, for describing ways to create languages (metamodels) for generating models that can then be realized. Metamodeling techniques are related to Adaptive Object-Models in that they both have a “meta” model that is used for describing (or reflect) the business domain, there are usually special GUI tools for manipulating the model, and metadata is usually interpreted for the creation of the actual model [65]. The primary difference is that Metamodeling techniques usually focus on code generation instead of interpretation of the descriptive information at runtime, like AOMs do. There has been related work with UML, which is the closest metamodeling language towards being realized for working systems. A good example can be seen by the work on the UML Virtual Machine [10]. Finally, AOMs are related to Reflective Techniques because they are a particular kind of reflective architecture that can dynamically adapt at runtime to new user requirements.. 12.

(24) Chapter 3 AspectJ. This chapter presents a brief background about Aspect-Oriented Programming and focuses on AspectJ language, presenting its constructs and its power in order to obtain separation of concerns.. 13.

(25) Aspect-oriented programming (AOP) emerged as a technique to solve the issues raised by some design decisions. These design decisions could not be well solved in object-oriented programming because their implementation crosscuts many parts of the code, or the program basic functionality. One of the AOP languages most widely used is AspectJ, which is a general-purpose AO extension to Java [27]. This chapter aims at introducing AspectJ, giving an overview about AOP and explaining each of the language constructions, illustrated by examples.. 3.1. Aspect-Oriented Programming. This section presents Aspect-Oriented Programming, which is a technology intended to provide clear separation of concerns [18] and whose main goal is to make design and code more modular, meaning the concerns are localized rather than scattered and have well-defined interfaces with the rest of the system. Initially, we give an overview about Separation of Concerns.. 3.1.1. Separation of Concerns. Separation of concerns is one of the principles of Software Engineering that apply throughout the software development process [24, 73]. It allows us to deal with different individual aspects of a problem, concentrating on each separately. During development, many decisions must be made. These decisions must be well isolated from each other. However, many decisions are strongly related and interdependent, and it is practically impossible to take all the issues into account at the same time. So, in order to master the complexity of a project, we need to separate the different concerns. We can separate concerns in many ways: in time, which allows for precise planning of activities; in terms of qualities that should be treated separately; allowing different views of the software to be analyzed separately. This helps us understand the system, even do not having a complete view of it; dealing with parts of the same system separately, which is related to the principle of modularity. In its most general form, separation of concerns refers to the ability to identify, encapsulate, and manipulate those parts of software that are relevant to a particular concept, goal, task, or purpose [73]. Concerns are the primary motivation for organizing and decomposing software into smaller, more manageable and comprehensible parts, each of which addresses one or more concerns. Aspect-Oriented programming is a new evolution in the line of technology for separation of concerns [18]. Besides it, other approaches have also been considered, such as: Adaptive Programming [48], Subject-Oriented Programming [32], Compositional Filters [5], and Intentional Programming [67], among others.. 3.1.2. Aspect-Oriented Paradigm. Object–oriented programming has been pointed out as the dominant programming paradigm [19]. It emerged as a solution to better solve computational problems by decomposing each problem into objects and implementing these objects. Each object 14.

(26) should be a self-contained unit with no understanding of its environment, and its environment should be aware of only what the object reveals [46]. However, some kinds of problems cannot be well solved by simply using OOP techniques [39]. That happens because those problems crosscut the system’s basic functionality, and sometimes force their implementation to be scattered throughout the code, resulting in tangled code, which is difficult to develop and maintain. Aspect-oriented programming is a programming technique created to solve the issues raised by some design decisions that are difficult to cleanly capture in code [39]. Those issues are called aspects. AOP is intended to provide appropriate isolation, composition and reuse of the code used to implement those aspects. This programming paradigm proposes that computer systems are better programmed by separately specifying the various concerns (properties or areas of interest) of a system and some description of their relationships and then, by using AOP environment, these concerns are composed or weaved together into a coherent program [19]. This is especially useful when the concerns considered are crosscutting. Crosscutting concerns are those that correspond to design decisions that involve several objects or operations, and that, without AOP, would lead to different places in the code that do the same thing, or do a coordinated simple thing. Some examples of crosscutting concerns are: logging, distribution, persistence, security, authentication, performance, transactions integrity, etc. OO implementations of these concerns may lead to the following problems [46]: • Classes that are difficult to change • Code that cannot be reused • Code that is difficult to trace In order to solve those problems, we can use refactoring. However, in most cases, the code for the system components is intertwined, and factoring becomes too costly. Nevertheless, AOP allows the refactoring to be performed on a different level and in a manner that helps to eliminate some of the tangled code. It is not meant to replace OOP or other object-based methodologies. Instead, it supports the separation of components, typically using classes, and provides a way to separate aspects from the components. An AOP-based implementation of an application consists of [39]: • A component language used to program the components; • One or more aspect languages with which to program the aspects; • An aspect weaver for the combined languages; • A component program, that implements the components using the component language; and • One or more aspect programs that implement the aspects using the aspect languages. An example of an aspect language is AspectJ, whose component language is Java. In order to better understand the characteristics of AOP, we will present some details about AspectJ in the next sections. 15.

(27) 3.2. AspectJ Overview. AspectJ is a general-purpose aspect-oriented extension to Java [38] originated from a work by Gregor Kiczales and his colleagues at Xerox’s PARC [76]. It supports the concept of join points, which are well-defined points in the execution flow of the program [77]. It also has a way of identifying particular join points (pointcuts) and change the application behavior at join points (advice). Pointcut designators identify particular join points by picking out a subset of all the join points in the program flow [38] and values at those points. A pointcut example is shown in the following: pointcut showingScreen(): execution (public void showScreen(byte)) ;. This pointcut captures the execution of any public method called showScreen that has a byte parameter and has void as its return type. This is just one example of the several kinds of pointcuts AspectJ provides. Advice declarations are used to define code that runs when a pointcut is reached. For example, we can define code to run before a pointcut, as the following example shows: before(): showingScreen(){ System.out.println("A screen will be shown"); }. With this advice, a message is displayed on the standard output before the execution of the showScreen method. Besides the before advice, AspectJ also provides after and around advice. The first runs after the computation under the join point finishes. The second runs when the join point is reached, and has explicit control over whether the computation under the join point is allowed to run at all [77]. AspectJ also has a way of affecting a program statically. With Inter-type declarations a program static structure can be changed. For example, we can change the members of a class and the relationship between classes. The following code illustrates how we can insert a new constant into the DictionaryController class: public static final byte DictionaryController.REGISTRATION_SCREEN=-3;. In AspectJ, we also have the concept of an aspect, which is a modular unit of crosscutting implementation. It is defined very much like a class, and can have methods, fields, constructors, initializers, named pointcuts, advice and inter-type declarations. For instance, we could have the following aspect definition: public aspect Screens {. }. Aspects are defined by grouping pointcuts, advice, and inter-type declarations. The aspect code is combined with the primary program code by an aspect weaver [79]. In the next section, we present more details about the language and its constructs.. 16.

(28) 3.3. AspectJ Language. AspectJ is a simple and practical aspect-oriented extension to Java. With just a few new constructs, AspectJ provides support for modular implementation of a range of crosscutting concerns [77]. By using aspects written in AspectJ, we can affect the normal execution of a program written in Java, which is the component language of an AOP-based implementation using AspectJ. In this section we present in details each of the language constructs, which are: pointcuts, advice, inter-type declarations and aspects. In order to illustrate each construct, most examples shown will be based on a Java implementation of a figure editor system whose UML class diagram is illustrated by Figure 3.1. The details given are based on AspectJ 1.1 version.. Figure 3.1: Figure Editor Example. 3.3.1. Join Points and Pointcuts. As we have already seen, join points are certain well defined points in the execution flow of a program. AspectJ defines many kinds of join points [77]: • Method call : when a method is called, not including super calls of non-static methods. • Method execution: when the body of code for an actual method executes. • Constructor call : when an object is built and that object’s initial constructor is called (i.e., not for super or this constructor calls). • Constructor execution: when the body of code for an actual constructor executes, after its this or super constructor call. • Static initializer execution: when the static initializer for a class executes. 17.

(29) • Object pre-initialization: before the object initialization code for a particular class runs. This encompasses the time between the start of its first called constructor and the start of its parent’s constructor. • Object initialization: when the object initialization code for a particular class runs. This encompasses the time between the return of its parent’s constructor and the return of its first called constructor. • Field reference: when a non-constant field is referenced. • Field set: when a field is assigned to. • Handler execution: when an exception handler executes. • Advice execution: when the body of code for a piece of advice executes. In order to pick up join points, AspectJ provides pointcuts designators, such as this, target, call, execution, args, etc. Some examples of pointcuts to capture points in the execution flow of the figure editor example from Figure 3.1 are shown in the following: execution(voidPoint.setX(int)) call(voidPoint.setX(int)) this(Point) target(FigureElement) handler(PointOutOfBoundsException). args(int) within(Display) cflow(call(voidDisplay.paint())). When the setX method body, from class Point, with an int parameter, executes When the setX method is called When the object currently executing (i.e. this) is of type Point When the target object is of type FigureElement When an exception handler executes (the catch block for PointOutOfBoundsException) When the executing or called method has an int parameter When the executing code belongs to class Display When the join point is in the control flow of a call to a Display’s no-argument paint method. Table 3.1: Pointcut Examples. The pointcuts shown in these examples are called primitive, and they can compose through the operations or (||), and (&&) and not (!). So, in order to capture the joint points correspondent to calls to setX or setY methods in a Point object that are not performed within class Display, we would have the following pointcut definition: (call(void setX(int)) || call(void setY(int))) && target(Point) && !within(Display). 18.

(30) It is possible to use wildcards in the pointcut definitions. The following examples illustrate a pointcut relative to the execution of any method regardless of return or parameter types (a) and another one that picks up the calls to any method named set regardless of return or parameter types (b) : a) execution(* *(..)) b) call(* set(..)). In order to improve reuse, the user can define a pointcut by specifying its name and parameters, besides the designators that identify the join points it picks out, as the following code illustrates: pointcut setter(): target(Point) && (call(void setX(int)) || call(void setY(int)));. As we can observe, the pointcut above does not present parameters. By using parameters, besides picking out join points, we can expose part of the execution context at join points. Values exposed by a pointcut can be used in the body of advice declarations. The following example illustrates a pointcut definition with a parameter: pointcut setter(Point p): target(p) && (call(void setX(int)) || call(void setY(int)));. This version of the setter pointcut picks out exactly the same join points as the one previously shown. But in this version, the pointcut has one parameter of type Point. This means that any advice that uses this pointcut has access to a Point from each join point picked out by the pointcut through the variable named p.. 3.3.2. Advice. As we could see, we can pick out join points by using pointcuts. In order to actually implement crosscutting behavior, we use advice. An advice defines pieces of aspect implementation that execute at well-defined points in the execution of a program. These points can be given by named or anonymous pointcuts. The following example illustrates a possible implementations of a before advice, which is responsible for including the execution of its body instructions before the points identified by the setter pointcut, shown in the previous example. before(Point p): setter(p){ System.out.println("Point "+p +"will change"); }. This advice prints a message before every call to setX or setY methods on a Point object. As the Point object is a pointcut parameter, the context is exposed and the current value of the object identified by “p” can be printed. Another possible implementation of this advice, using an anonymous pointcut this time would be: before(Point p): target(p) && (call(void setX(int)) || call(void setY(int))){ System.out.println("Point "+p +"will change"); }. 19.

(31) With the AspectJ IDEs, such as the one offered for Eclipse [74], we can better visualize the points in the code that are affected by an advice. For the previously defined before advice with a named pointcut, considering the figure editor example, we would have in the Outline view of Eclipse an image like the one illustrated by Figure 3.2. Through this image we can see that a message will be printed before the calls to setX inside the main method, from class Main, and the method moveBy from class Point and also before the call to setY within moveBy method from class Point.. Figure 3.2: Before advice example using Eclipse IDE for AspectJ. Besides before, AspectJ provides other kinds of advice. All of them are shown in Table 3.2: In order to explain some of these advice, we can consider the figure editor before after returning. after throwing. after around. Runs before each join point Runs after each join point that returns normally. We can optionally specify the returned value. By doing that, it can be accessed. Runs after each join point that throws a Throwable. If we specify the type of Throwable, this advice runs only after each join point that throws the specific Throwable and we have access to the Throwable exception value. Runs after each join point regardless of whether it returns normally or not Runs in place of each join point. The join point can be executed by calling proceed, which takes the same number and types of arguments as the around advice. Table 3.2: AspectJ Advice. example again, with the problem of display updating, which is a crosscutting one. Every change in the position of a point, or move of a line or other figure must trigger a repaint of the display. We would not achieve a good separation of concerns if we inserted in the Point or Line classes the code necessary to invoke a repaint on the display, as a Point or a Line object must not be worried about a Display one. With AspectJ, we can define, in an isolated module (an aspect) the pointcut and advice necessary to perform the update, as the following code illustrates:. 20.

(32) aspect DisplayUpdating { pointcut move(): call(void FigureElement.moveBy(int, int)) || call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() returning: move() { Display.needsRepaint(); } }. The after advice defined above invokes the needsRepaint method on Display when any of the join points picked out by the move pointcut happen and no Throwable is thrown. In order to exemplify the after throwing advice, we will consider the following example: after(Point p) throwing (PointOutOfBoundsException e) :setter(p){ errorLogger.write("Error while moving point "+p+":"+e.getMessage()); }. With this advice, we can write in the error log file a message specifying the Point where a move was performed and the message of the exception thrown. This is done without including any lines of code in other places of the system. In order to substitute or change the normal execution of a join point, we use the around advice. The example in the following shows how we can change the setX method execution. void around(int x): execution(void setX(int)) && args(x) { if (x>=0 && x<=100){ proceed(x); } else{ proceed(10); } }. In the advice previously defined, we expose the int parameter, called x, which is an argument of the setX method. In the advice body, we check if this argument is within a certain range(0-100). If it is, the execution proceeds normally. Otherwise, the execution proceeds, but the x argument value is changed to 10. Reflective Access Within the advice body, we can have reflective access to the join point by three special visible variables: thisJoinPoint, thisJoinPointStaticPart, and thisEnclosingJoinPointStaticPart. Each is bound to an object that encapsulates some of the context of the advice’s current or enclosing join point. These variables exist because some pointcuts may pick out very large collections of join points, such as the following pointcut: 21.

(33) pointcut publicCall(): call(public * *(..));. By using such variables, the body of advice may have access to the method name or parameters of a particular join point. They can be very useful for tracing. We could define the following advice for tracing all calls to public methods in a program: before(): call(public * *(..)) { System.out.println("Entering:" + thisJoinPoint); }. In the standard output, we could have messages correspondent to each application method call, such as: Entering:call(void figures.Point.setX(int)). 3.3.3. Inter-type Declarations. Inter-type declarations correspond to the aspects property of declaring members (fields, methods, and constructors) that are owned by other types (inter-type members) or of declaring that other types implement new interfaces or extend a new class. An example of an inter-type member declaration is shown in the following: public String Point.getXY(){ return "("+this.getX()+","+this.getY()+")"; }. This code publically declares a method in class Point, that can be invoked anywhere a Point object is accessible. Inside this new method body, this corresponds to the Point object currently executing. The declaration of a new constructor to a class is similar, as the following example illustrates: public Point.new(int x, int y) { this.x = x; this.y = y; }. With the code above, we declare a two-parameter constructor on class Point that can be called anywhere the Point class is visible. We can also declare a field in this class, almost the same way we would do in the class body, just including the name of the class before the field name: public static final int Point.MAX X= 100;. A useful application of the inter-type declaration property is for the implementation of the Observer design pattern [23] with aspects, which is discussed in another work [31]. In order to make a class implement the Subject or Observer interfaces, proposed by the pattern, we do not need to directly change the class, but, instead, to define the new relationship in an isolated aspect. Suppose we have in the figure editor example a class called Screen and an application with multiple Screen instances, that should be notified about any changes on FigureElement objects. Using inter-type declaration we would have: declare parents: Point implements Subject; declare parents: Line implements Subject; declare parents: Screen implements Observer;. Then, using pointcuts and advice, we can determine the execution points that should trigger the update of Observers according to the Subjects’ state and invoke this update. 22.

(34) 3.3.4. Aspects. As we have seen on Section 3.2, aspects are defined very much like a class, but can also present pointcuts, advice, and inter-type declarations, which are called crosscutting members. The aspects’ members are illustrated by Figure 3.3.. Figure 3.3: Aspect members We can say that an aspect is a crosscutting type, which is defined by the aspect declaration. It may not be directly instantiated with a new expression, with cloning, or with serialization. Aspects may have one constructor definition, but if so, it must take no arguments and throw no checked exceptions. They may be defined either at the package level, or as a static nested aspect (a static member of a class, interface, or aspect), and, in the latter case, they must be defined with the static keyword. Local and anonymous aspects are not allowed. By default (or by using the modifier issingleton after the aspect name) an aspect has exactly one instance that cuts across the entire program. That instance is available at any time during program execution with the static method aspectOf defined on the aspect. However, there are situations, especially when creating reusable aspects, where it is desirable to associate the aspect’s state with an individual object or control flow. In these cases, the following modifiers for aspects are used: • perthis(Pointcut): An aspect instance is created for every object that is the executing object (i.e., “this”) at any of the join points picked out by Pointcut. • pertarget(Pointcut): An aspect instance is created for every object that is the target object of the join points picked out by Pointcut. • percflow(Pointcut): An aspect instance is created for each entrance to the control flow of the join points picked out by Pointcut. 23.

(35) • percflowbelow(Pointcut): An aspect instance is created for each entrance to the control flow below the join points picked out by Pointcut. In the case of perthis and pertarget, we must access the aspect instance registered with an specific Object by the aspectOf(Object) method. Aspect Extension Aspects can be extended in much the same way that classes can, but some new rules are applied. For example, they may extend other aspects, classes and implement interfaces. However, a class may not extend or implement an aspect. When an aspect extends another one, not only fields and methods are inherited, but also pointcuts. It is important to notice, however, that aspects may only extend abstract aspects. An abstract aspect must declare itself as abstract and can mark any pointcut or method as abstract. This allows a base aspect to implement the crosscutting logic without needing the exact details that only a system specific aspect can provide. Aspect Privilege While the same restrictions in relation to acess control are applied to aspects and pure Java code, there may be some aspects in which advice or inter-type members need to access private or protected resources of other types. In order to allow this and even the access to private inter-type declarations made by other aspects, aspects may be declared privileged. Suppose the x and y fields of the Point class are private, we could have a privileged aspect like the following: privileged public aspect PrivTest { before (Point p, int x, int y): execution(void moveBy(int,int)) && args(x,y) && this(p){ if ((p.x+ x)>100 || (p.y+y)>100) throw new PointOutOfBoundsException("Invalid Move"); } }. As we can observe, this privileged aspect can access the x and y fields, even though they are private members of the Point class inside its before advice body and use their values in order to check if the move would be illegal.. 3.3.5. Types of crosscutting. AspectJ enables both name-based and property based crosscutting. Aspects that use name-based crosscutting tend to affect a small number of other classes, because their pointcuts are based on explicit enumeration of a set of method signatures. But despite their small scale, they can often eliminate significant complexity compared to an ordinary Java implementation. When we specify a pointcut in terms of properties of methods other than their exact name, we have property-based crosscutting. The simplest of these involve using wildcards in certain fields of the method signature, as the following pointcut illustrates: 24.

(36) call(void Figure.make*(..)). It picks out each join point that is a call to a void method defined on Figure whose name begins with “make” regardless of the method’s parameters, and so, the factory methods makePoint and makeLine. Another pointcut designator, cflow, identifies join points based on whether they occur in the dynamic context of other join points and also characterizes property-based crosscutting. The following pointcut, for example, picks out each join points that occurrs between when a moveBy method is called and when it returns: cflow(call (void moveBy(int,int)));. 3.3.6. Program Composition. AspectJ provides its own weaver and compiler, that can be accessed by the “ajc” command. It compiles AspectJ and Java language files, weaving aspects as necessary to produce .class files compliant with any Java VM (1.1 or later). As input for the compiling and weaving process, we must supply source files, that can be aspects or standard Java files. They may be listed directly in the command line or in a description file, or their directories may be specified. Besides them, we may also enter .jar files containing already compiled classes or aspects, which will be included in the output and possibly woven with any applicable aspects.. 3.3.7. Other Approaches. Besides AspectJ, there are other AOP approaches: • AspectC++, which is intended to extend the AspectJ approach to C/C++ [71]; • AspectS, which is an approach to general-purpose aspect-oriented programming in the Squeak/Smalltalk environment [33]. It mainly draws on the results of two projects: AspectJ, and MethodWrappers [6]; • AspectR, which is intended to provide simple aspect-oriented programming in Ruby [68]; • AspectC# [41], which is a tool that provides aspect-oriented programming (AOP) constructs, pioneered by AspectJ, for the C# language; etc. Besides AspectJ-like languages, other approaches have also been considered for dealing with separation of concerns. One of them, very related to the AspectJ language is Adaptive Programming [48]. It explores AOP ideas through DJ Library [30], and is based on the notion of adaptive methods, which encapsulate the behavior of an operation into one place. To do this, the behavior is expressed as a high-level description of how to reach the participants of the computation (called a traversal strategy), plus what to do when each participant has been reached (called an adaptive visitor). The DJ (Demeter/Java) library is a Java package that supports this style of programming by providing tools to interpret a traversal strategy and an adaptive visitor in the context of the underlying class structure. With it, we can explore AOP ideas, without learning a language extension. However, only a limited class of behavioral concerns can be expressed as adaptive methods. 25.

(37) Chapter 4 Introducing Adaptive Behaviors with Aspects. This chapter aims at presenting the problems found in the implementation of adaptive applications and how we can minimize them through the use of AspectJ, exploring the domain of J2ME applications. We also show some techniques for representing and retrieving data for dynamic adaptations using some Adaptive Object-Model ideas.. 26.

(38) Building self-adaptive applications is a task which is both complex and challenging. The development of such applications involves several issues in addition to the implementation of the application-specific functionalities [66]. In order to minimize this complexity, especially in adaptive distributed applications, there is an approach [66, 11] based on a framework that provides a set of integrated tools for monitoring resource usage and component interactions, detecting composite events, and reconfiguring distributed applications. However, some adaptive behaviors crosscut the application functionalities. Besides that, the actions taken as a result of a context change may involve several parts of the application. This makes it difficult to well isolate those actions in code using pure object-oriented approaches. A known technique for code modularization is the use of design patterns [23]. Another solution is the use of Aspect-Oriented Programming [39]. In this chapter, we discuss how AspectJ can be used to implement some adaptive behaviors and its advantages and drawbacks compared to the use of common Object-Oriented patterns. We also discuss ways to represent data used for dynamic adaptations. In order to illustrate AspectJ use for implementing adaptive behaviors, we have used a Java 2 Micro Edition (J2ME) [60] dictionary application without adaptive requirements, which is explained in the following section.. 4.1. The Dictionary Application. The dictionary presented in this section is implemented in J2ME. J2ME is a lean Java platform targeted specifically at applications running on small devices such as mobile phones, PDAs, Internet screenphones, digital television set-top boxes, automotive entertainment and navigation systems, network switches, home automation components, among others [20]. With the purpose of supporting such devices, J2ME adopts a modular and scalable architecture. It defines three layers of software built upon the native operating system of the device: the Java Virtual Machine Layer, the Configuration Layer and the Profile Layer. K Virtual Machine(KVM), Connected Limited Device Configuration(CLDC) and Mobile Information Device Profile(MIDP) all form the foundation for developing wireless Java applications. Such applications can be executed on cell phones and two-way pagers that follow this architecture. Throughout this dissertation, when referring to J2ME applications, applications that run on KVM/CLDC/MIDP architecture are meant. The dictionary application is a cellular phone application that is capable of translating words from English into Portuguese. It is a very simple but typical MIDP-based application (also known as MIDlet [52, 60]). It is able to run on devices with limited resources, such as memory size and processor power. The dictionary without adaptive behaviors presents four screens: presentation, main menu, instructions and search screens which are illustrated by Figure 4.1. The main menu presents two options: Query and Instructions. In search screen the search is requested and the translation results are shown. None of these screens is colorized. The dictionary searches the requested English word on memory and displays its Portuguese translation on the screen. The application structure follows the Model View Controller architectural pattern [23]. The main classes are DictionaryMIDlet and DictionaryController, which refers 27.

(39) to a DictionaryEngine object that is responsible for the search (see Figure 4.1).. Figure 4.1: Dictionary application UML model. The DictionaryMIDlet class inherits from the javax.microedition.midlet.MIDlet class and must be specified on the application descriptor file (the JAD file). The DictionaryController class is the controller and manages the application screens, its main operations, and properties. The screens, or the view element of the MVC, are represented by four classes, which implement the javax.microedition.Displayable interface: SearchScreen, InstructionsScreen, MainMenuScreen, and PresentationScreen. All of them refer to the single controller instance in order to notify it when their commands are selected by the user. The model element of the MVC is represented by the DictionaryEngine class and InputSearchData, which is a class representing some application properties, such as the source and destination languages used for the translation, and the word to be translated. As we can see, this application is not adaptive. In the following section we present some changes performed on the application in order to make it able of changing its behavior according to context changes, such as new data representing its behavior.. 4.2. Developing Adaptive J2ME Applications Using AspectJ. In this section, the AspectJ [38] language, a general-purpose aspect-oriented extension to Java [27], is evaluated as a tool to develop adaptive Java applications, especially the Java 2 Micro Edition (J2ME) [60] ones. Although focusing on this platform, many of our results can be applied to other Java platforms. We use J2ME for it is targeted to application domains that have adaptability as a common requirement. This section contents corresponds to a previously published work [17].. 28.

Referências

Documentos relacionados

 O consultor deverá informar o cliente, no momento do briefing inicial, de quais as empresas onde não pode efetuar pesquisa do candidato (regra do off-limits). Ou seja, perceber

Local Estádio Montenegro Machado – Sintético, Repeses Campo de Treinos Estádio São Miguel – Sintético, Gondomar Campo de Treinos Estádio Municipal 25 de Abril –

Todos estos problemas convirtieron la imagen de la biblioteca pública en la de una institución pasiva ante los problemas de la comunidad y, también pasivamente, la biblioteca

- Crianças com vinculação evitante, têm uma adaptação à creche aparentemente fácil, pois o bebé é mais passiva, não pede atenção e “foge” do

O presente trabalho teve como objetivo minimizar o sabor amargo da carne escura de atum (Euthynnus pelamis), através da fermentação lática, utilizando Lactobacillus casei subsp...

Ousasse apontar algumas hipóteses para a solução desse problema público a partir do exposto dos autores usados como base para fundamentação teórica, da análise dos dados

Atividades dos homens e da igreja, se dão ao longo da história e em certo contexto. Sem considerarmos a historicidade dos homens e das instituições por elas

5) As partes devem cooperar para promover um sistema econômico in- ternacional favorável e aberto conducente ao crescimento e ao desen- volvimento econômico sustentáveis de todas