In this article we will try to define a classification of projects that deal in one way or the other with the migration of code or data. This classification is not strictly hierarchical, since in general too many aspects overlap. However, the intent of this document is not to deliver a scientifically precise hierarchy, but to provide you with practical ideas when dealing with migration.
Specifying a classification for your current (migration) project will help you to clarify its objective and the impact it will have on your system. Each class is related to a set of patterns and tools, where you will often be required to define your own proven tool box. Useful tools will be the subject of a future post.
Class 0: Code refactorings
Well, that means, in other words, every day’s work. But in fact, refactorings such as renaming or extracting methods, optimizing code, adding new modules, etc., represent the continuous migration of code. This very low-level kind of migration is the base of almost all other migration classes.
Class 1: Implementing new functionality
At first sight this seems not to deal with migration issues at all. Actually, implementing new features will in many cases require a data migration, adding or dropping columns and tables, for example. Usually you will accomplish that with a delta script.
For more complicated cases you can use tools like GuttenBase to execute the migration.
Class 2: Upgrade or add framework/library
We probably all experienced that upgrading a library can have surprising effects. The API may have changed or are there incompatible methods, the library may depend on other libraries in versions incompatible to your other code. Thus, this is a migration, too, which needs to be verified by the compiler, extensive unit and user tests.
Class 2.1: Change framework implementation
If your application uses frameworks with a public API that has multiple competing implementations, e.g. JPA, the project theoretically may use a different implementation from one day to the other. Actually, we never experienced a real-life project, where this worked out of the box.
Changing a framework implementation such as moving from Hibernate to EclipseLink barely ever happens anyway, thus we do not further elaborate on that.
Class 3: Moving to a new platform
Yet what sometimes comes into play is to change a third-party system. A typical example is the migration of code from one application server to another. Reasons for doing so can be licensing costs and performance. There are tools to assist you in detecting critical pieces of code, i.e. code that depends on proprietary behavior. JBoss, e.g ,offers a tool named Windup that will help you to move from another application server
Class 4: Architectural and technical changes
As you will also have experienced, applications and their architectures age over time. What might have seemed the best choice at the start of the project is now considered cumbersome and not maintainable anymore. Newer technologies offer more features and promise to do things better. However, such an upgrade of technologies is a serious decision and should be well-considered.
One example where you really may profit from such a break is to migrate from custom JDBC to a framework like Hibernate/JPA. One thing you get for free then is first- and second-level caching, e.g..
Class 5: Isolate functionality and move or reimplement it on a new system
Sometimes you have a running system that will not or cannot be updated anymore, but increasingly causes performance or availability problem. That may be because the original architecture is not sufficient to handle the current amount of data or the number of requests anymore. Adding more memory or buy faster machines may appease for a while. But often the fundamental problem needs to be tackled by isolating critical services and re-implementing them.
We once had to deal with the performance problems of an application that used an XML database, which was completely inappropriate for the domain of the application. We solved them by reimplementing the services using a standard RDBMS and adding a caching mechanism.
Class 6: Reimplement application
This of course is the most radical approach thinkable. However, there are examples especially in the open source community where the developers had learned some lessons and chose to start anew. The JBoss application server 8 (“WildFly”), e.g., has been built from scratch.
This scheme of classification is certainly not complete. Maybe you have a different view, so please feel invited to add some comments on this topic.
In an upcoming article we will give more examples and speak about useful tools and practices.