Automated upgrading of component-based applications
Authors: Ralph Johnson
Venue:  (2007)

Software developers like to reuse software components such as libraries or frameworks because it lets them build a system more quickly, but then the system depends on the components that they reused. Ideally, the programming interface (API) to a component never changes. In practice, components change their APIs. Upgrading an application to the new API is error-prone, tedious, and disruptive to the development process. Although some tools and ideas have been proposed to solve the evolution of APIs, most upgrades are done manually. This makes maintaining software expensive. Our goal is to automate the upgrading and make it practical. Our study of the API changes in five components revealed that over 80% of the changes that break existing applications are caused by refactorings. Refactorings are program transformations that improve the structure of existing components. We suggest that refactoring-based upgrading tools can be used to effectively upgrade applications. We propose an approach that is both automated and safe, without any overhead on the component producers. First, component refactorings are automatically detected (either inferred or recorded), then they are incorporated into applications by replaying. This is the process used to automate the upgrading of applications: along with the new version of the component, component developers ship the log of refactorings applied to create the new version. An application developer can then upgrade the application to the new version by using a refactoring tool to replay the log of refactorings. We developed a toolset to automatically upgrade applications in response to component refactorings. First, we developed a record-and-replay extension to a refactoring engine which records component refactorings and replays them on the applications. To handle those cases when component refactorings are not recorded, we developed RefactoringCrawler, a tool that detects refactorings in Java components. The empirical evaluation of RefactoringCrawler shows that it scales to real-world components, and its accuracy in detecting refactorings is over 85%, a significant improvement over existing solutions. Not only components evolve, but applications evolve too. Besides refactorings, components and applications evolve through edits. Refactorings and edits can interfere with each other thus impeding the replay. To address this, we developed MolhadoRef, the first software merging system that intelligently merges refactorings and edits from components and applications, therefore upgrading the applications. Experimental evaluation shows that MolhadoRef automatically resolves more merge conflicts than traditional text-based systems while producing fewer merge errors. To address those cases when the source code of the application cannot be changed in response to component refactorings, we developed a tool, RefactoringBinaryAdapter (ReBA). ReBA automatically generates an adapter between component and application thus enabling old binary applications to run with the latest version of the component without requiring changes in the application. Not only does our toolset reduce the burden of manual upgrades, but it will influence component designers as well. Without fear that they break the existing applications, designers will be bolder in the kind of changes they can make to their designs. Given this new found freedom, designers will continue to refactor the design of software components to make them easier to understand and use.