Reverse engineering techniques are usually applied to extract concrete architecture models. However, these techniques usually extract diagrams that just reveal static architectures, such as class diagrams. On the other hand, the extraction of dynamic architecture models can be particularly useful for an initial understanding of how a system works or to evaluate the impact of a possible maintenance task. This paper describes an approach to extract hierarchical object graphs from running systems. The proposed graphs have several features that – when combined – make them valuable when compared to similar approaches, including: (a) support to the hierarchization of objects in domains, (b) support to the full spectrum of relations and entities that are common in object-oriented systems, (c) support to multithreading systems, (d) support to a language to alert about expected (or unexpected) relations between extracted objects. We also describe the design and implementation of a tool for visualizing the proposed object graphs. Finally, we show how our approach can contribute for understanding the running architecture of two systems. Resumo—Técnicas de engenharia reversa são frequentemente usadas para extrair uma representação da arquitetura implementada de um sistema. No entanto, essas técnicas normalmente permitem a extração apenas de diagramas que revelam a arquitetura estática de um sistema, tais como diagramas de classe. Por outro lado, o estudo da arquitetura dinâmica de um sistema pode ser particularmente útil quando se deseja formar um primeiro entendimento do funcionamento de um sistema ou avaliar o impacto de uma possı́vel manutenção no mesmo. Sendo assim, descreve-se neste artigo uma abordagem que permite a recuperação de um grafo de objetos a partir da execução de um sistema existente. O grafo proposto possui diversas caracterı́sticas que – quando combinadas – o distinguem de outras abordagens semelhantes, incluindo: (a) suporte a grupos de objetos de maior granularidade, chamados domı́nios; (b) suporte aos diversos tipos de relacionamentos e entidades que podem existir em sistemas orientados por objetos; (b) suporte a sistemas multithread; (c) suporte a uma linguagem para definição de alertas associados a relacionamentos que são esperados (ou que não são esperados) em um sistema. Adicionalmente, descreve-se o projeto e a implementação de uma ferramenta para visualização dos grafos de objetos propostos. Por fim, apresenta-se um estudo de caso que mostra como essa ferramenta pode auxiliar na compreensão da arquitetura dinâmica de dois sistemas. I. INTRODUÇÃO Arquitetura de software se preocupa em descrever os componentes principais de um sistema, bem como em especificar os relacionamentos possı́veis entre esses componentes [12], [6], [18]. Assim, a definição da arquitetura de um sistema envolve um conjunto de decisões que são crı́ticas para seu sucesso e que não poderão ser facilmente revertidas nas fases seguintes de seu desenvolvimento. No entanto, apesar de sua inegável importância, componentes e abstrações com valores arquiteturais não existem para a maioria dos sistemas ou, quando existem, eles não mais refletem a implementação atual desses sistemas [14], [8], [17]. Assim, técnicas de engenharia reversa são frequentemente usadas para extrair uma representação da arquitetura de um sistema [9], [24]. Normalmente, essas técnicas permitem a extração de diagramas que revelam a arquitetura estática de um sistema, tais como diagramas de classes [11], diagramas de pacotes [11] e matrizes de dependência estrutural [19]. Esses diagramas têm como principal vantagem o fato de serem recuperados diretamente do código fonte do sistema (isto é, sem a necessidade de execução). No entanto, eles apresentam uma versão parcial dos relacionamentos que são estabelecidos durante a execução de um sistema [1], [7], [13]. Por exemplo, diagramas estáticos não revelam relacionamentos estabelecidos por meio de polimorfismo e de chamada dinâmica de métodos, nem relacionamentos por meio do uso de reflexão computacional. Além disso, exatamente por serem estáticos, eles não possuem nenhuma informação sobre a ordem com que os diversos relacionamentos modelados foram de fato estabelecidos, o que é crucial para facilitar o entendimento por parte de usuários que não tenham familiaridade com os sistemas recuperados. Em outras palavras, para a compreensão de um sistema por meio de diagramas estáticos, desenvolvedores frequentemente têm a sensação de não saber por onde começar. Por fim, diagramas estáticos não fazem diferenças entre relacionamentos estabelecidos por diferentes threads, o que dificulta o entendimento de sistemas concorrentes (os quais têm se tornado cada vez mais comum em qualquer domı́nio de aplicação e não mais apenas na área de software básico). Por outro lado, existem técnicas de engenharia reversa que visam a extração de diagramas que revelam a arquitetura dinâmica de um sistema, tais como diagramas de objetos e de sequência [11]. Como principal vantagem, essas alternativas permitem expressar o fluxo de execução de um sistema, capturando inclusive relacionamentos decorrentes de chamadas dinâmicas e de reflexão computacional [20], [26]. No entanto, esses diagramas normalmente não são escaláveis, apresentando milhares de objetos mesmo para sistemas de pequeno porte [1], [2]. Além disso, modelos dinâmicos normalmente não fazem distinção entre objetos de mais baixo nı́vel (exemplo: java.util.Date) e objetos de maior valor arquitetural (exemplo: uma coleção de objetos do tipo Customer). As soluções propostas para melhorar a escalabilidade de diagramas dinâmicos se baseiam em um mesmo princı́pio: agrupar objetos em unidades de maior granularidade (normalmente denominadas domı́nios [1], componentes [15], clusters [4] etc), de forma a permitir uma visão hierarquizada do diagrama. No nı́vel mais alto dessa visão, são representados apenas grupos de objetos de maior valor arquitetural. Pode-se então expandir os grupos de uma visão de mais alto nı́vel, de forma a fornecer mais detalhes sobre seus elementos. Esse processo pode ser repetido sucessivas vezes, até se chegar a um grafo de objetos totalmente plano, onde cada elemento representado corresponde a um objeto do programa base. Basicamente, existem duas propostas de soluções para agrupar objetos em unidades de maior granularidade: soluções automáticas (por exemplo, usando algoritmos de clusterização [5], [4]) e soluções manuais (por exemplo, por meio de anotações no código [1], [2]). Usualmente, soluções automáticas têm a desvantagem de não gerar grupos de objetos semelhantes àqueles que seriam definidos pelo arquiteto do sistema. Por outro lado, soluções via anotações são invasivas, requerem um conhecimento prévio do sistema e uma inspeção detalhada no código para anotar cada classe com marcações indicando seu papel na arquitetura do sistema (exemplo: classes da camada de visão seriam anotadas com uma marcação View). Neste artigo, descreve-se uma abordagem que permite a recuperação de um grafo de objetos a partir da execução de um sistema existente. O grafo proposto possui diversas caracterı́sticas que o distinguem de outras abordagens semelhantes, incluindo: (a) suporte a grupos de objetos de maior granularidade, chamados domı́nios, os quais são definidos de forma não-invasiva, por meio de uma linguagem de expressões regulares; (b) suporte aos diversos tipos de relacionamentos e entidades que podem existir em um sistema orientado por objetos, incluindo relacionamentos devido a chamadas dinâmicas, reflexão computacional e relacionamentos entre objetos e campos estáticos de classes; (c) suporte a sistemas multi-thread por meio do uso de cores para diferenciar objetos criados por threads diferentes; (d) suporte a uma linguagem para definição de alertas associados a relacionamentos que são esperados (ou que não são esperados) em um sistema. Adicionalmente, descreve-se o projeto e a implementação de uma ferramenta para visualização dos grafos de objetos propostos. Essa ferramenta foi projetada de forma que ela pode ser “acoplada” a um sistema existente, permitindo assim a visualização do grafo de objetos proposto à medida que o programa base está sendo executado (ou seja, diferentemente de outras abordagens, não é preciso executar o sistema, para gerar um arquivo com o rastro da execução, que somente então será exibido para os usuários finais). Por fim, apresenta-se um estudo de caso que demonstra como a ferramenta pode auxiliar na compreensão da arquitetura dinâmica de dois sistemas. O restante deste artigo está organizado conforme descrito a seguir. Na Seção II, descrevem-se o grafo de objetos proposto, incluindo uma descrição de seus principais elementos e alguns exemplos. Na Seção III, descreve-se a linguagem de alertas, usada para notificar os arquitetos sobre o estabelecimento de relacionamentos que são desejados (ou que não são desejados) em um sistema. Em seguida, a Seção IV descreve a ferramenta para visualização dos grafos de objetos propostos, bem como de eventuais alertas definidos pelos arquitetos. A Seção V apresenta um estudo de caso, envolvendo o uso da ferramenta para visualizar e compreender dois sistemas construı́dos segundo o padrão arquitetural MVC (ModelView-Controller). A Seção VI discute trabalhos relacionados e a Seção VII conclui o artigo, resumindo as principais contribuições dos grafos de objetos propostos e delineando possı́veis linhas de trabalhos futuros. II. GRAFO DE OBJETOS Um OG (Object Graph) é um grafo direcionado que representa o comportamento dinâmico dos objetos de um sistema. Os vértices de um OG representam todos os objetos e algumas das classes de um sistema. As arestas representam os possı́veis relacionamentos entre os vértices do grafo. Detalhes sobre os vértices e arestas de um OG são fornecidos a seguir. Vértices: Um OG admite dois tipos principais de vértices. Vértices na forma de um cı́rculo são usados para representar objetos. Vértic
[1]
Ricardo Terra,et al.
A dependency constraint language to manage object‐oriented software architectures
,
2009,
Softw. Pract. Exp..
[2]
Paul Clements,et al.
Software architecture in practice
,
1999,
SEI series in software engineering.
[3]
Hong Yan,et al.
Discovering Architectures from Running Systems
,
2006,
IEEE Transactions on Software Engineering.
[4]
Ricardo Terra,et al.
Verificação Estática de Arquiteturas de Software utilizando Restrições de Dependência
,
2008,
SBCARS.
[5]
Robert L. Nord,et al.
Describing Software Architecture with UML
,
1999,
WICSA.
[6]
Kamran Sartipi,et al.
Dynamic Analysis of Software Systems using Execution Pattern Mining
,
2006,
14th IEEE International Conference on Program Comprehension (ICPC'06).
[7]
Nicolas Anquetil,et al.
Ten Years Later, Experiments with Clustering as a Software Remodularization Method
,
2009,
2009 16th Working Conference on Reverse Engineering.
[8]
Lionel C. Briand,et al.
Toward the Reverse Engineering of UML Sequence Diagrams for Distributed Java Software
,
2006,
IEEE Transactions on Software Engineering.
[9]
Jens Knodel,et al.
Static evaluation of software architectures
,
2006,
Conference on Software Maintenance and Reengineering (CSMR'06).
[10]
Mary Shaw,et al.
Software architecture - perspectives on an emerging discipline
,
1996
.
[11]
Ricardo Terra,et al.
Static Architecture-Conformance Checking: An Illustrative Overview
,
2010,
IEEE Software.
[12]
Stéphane Ducasse,et al.
Software Architecture Reconstruction: A Process-Oriented Taxonomy
,
2009,
IEEE Transactions on Software Engineering.
[13]
Richard N. Taylor,et al.
A Classification and Comparison Framework for Software Architecture Description Languages
,
2000,
IEEE Trans. Software Eng..
[14]
Hong Yan,et al.
DiscoTect: a system for discovering architectures from running systems
,
2004,
Proceedings. 26th International Conference on Software Engineering.
[15]
Nicolas Anquetil,et al.
Experiments with clustering as a software remodularization method
,
1999,
Sixth Working Conference on Reverse Engineering (Cat. No.PR00303).
[16]
Paolo Tonella.
Reverse engineering of object oriented code
,
2005,
ICSE.
[17]
P. Tonella.
Reverse engineering of object oriented code
,
2005,
Proceedings. 27th International Conference on Software Engineering, 2005. ICSE 2005..
[18]
Martin Fowler,et al.
Patterns of Enterprise Application Architecture
,
2002
.
[19]
Daniel Jackson,et al.
Lightweight extraction of object models from bytecode
,
1999,
Proceedings of the 1999 International Conference on Software Engineering (IEEE Cat. No.99CB37002).
[20]
Philippe Kruchten,et al.
The 4+1 View Model of Architecture
,
1995,
IEEE Softw..
[21]
Marwan Abi-Antoun,et al.
Static extraction of sound hierarchical runtime object graphs
,
2009,
TLDI '09.
[22]
Claudio Riva,et al.
Combining static and dynamic views for architecture reconstruction
,
2002,
Proceedings of the Sixth European Conference on Software Maintenance and Reengineering.
[23]
Mary Shaw,et al.
"The Golden Age of Software Architecture" Revisited
,
2009,
IEEE Software.
[24]
Alexander Ran,et al.
Third Eye - specification-based analysis of software execution traces
,
2000,
Proceedings of the 2000 International Conference on Software Engineering. ICSE 2000 the New Millennium.
[25]
Farhad Mavaddat,et al.
Architectural design recovery using data mining techniques
,
2000,
Proceedings of the Fourth European Conference on Software Maintenance and Reengineering.
[26]
Ricardo Terra,et al.
Towards a Dependency Constraint Language to Manage Software Architectures
,
2008,
ECSA.
[27]
Jens Knodel,et al.
A Comparison of Static Architecture Compliance Checking Approaches
,
2007,
2007 Working IEEE/IFIP Conference on Software Architecture (WICSA'07).
[28]
David Notkin,et al.
Software reflexion models: bridging the gap between source and high-level models
,
1995,
SIGSOFT FSE.
[29]
David Notkin,et al.
ArchJava: connecting software architecture to implementation
,
2002,
ICSE '02.
[30]
Ivar Jacobson,et al.
The Unified Modeling Language User Guide
,
1998,
J. Database Manag..
[31]
Vineet Sinha,et al.
Using dependency models to manage complex software architecture
,
2005,
OOPSLA '05.
[32]
Alexander L. Wolf,et al.
Acm Sigsoft Software Engineering Notes Vol 17 No 4 Foundations for the Study of Software Architecture
,
2022
.
[33]
Marwan Abi-Antoun,et al.
Static extraction and conformance analysis of hierarchical runtime architectural structure using annotations
,
2009,
OOPSLA '09.