In one of my latest project, I’ve had to migrate a J2EE application from a Windows server to a Linux server. I didn’t know the code before I was assigned the task (which was to be completed ASAP).
It’s a pretty interesting task. In fact I’ve completely failed at evaluating the time it would take. And luckily for me, I didn’t have to migrate to a different J2EE server or DB server. Here are some of the issues I encountered, most of them related to un-portability.
- name cases: Windows tends to ignore file casing while Linux is more sensitive. Had issues in DB table names (MySQL), file paths in xsl files referencing font files, …
- non portable hardcoded defaults: OS specific File paths (/temp anyone?), use of default Locale or charset which affected XSL file reading and PDF generation
- issues related to file encodings (some xsl files had lost their original encodings). As it is not possible to know for sure the encoding of a file, and as no documentation was available, I could only troubleshoot the problem at deployment time
- bugs that trigger only on a particular OS (e.g. code executed inside an if block whose condition doesn’t evaluate on the original server but does on the new one)
- JBoss behaving differently on the new server. The code was incorrect anyway as it was using Exception handling for flow management (ignoring a javax.ejb.NoSuchObjectLocalException…). I haven’t found the exact reason for the different behavior, but I suspect a different JDBC driver version or different DB version. The problem was solved by removing dirty data from the DB which caused the original exception to not be thrown anymore
- Database specific bugs: the DB I was using on my Linux development machine had a bug that was particular to the distribution I was using, so I’ve had to get the DB server from the vendor site instead. Talk about luck.
- Oh and did I mention that I didn’t get the code matching the version of the software running on the production server?
Things that could have gone wrong but didn’t (so far):
- lack of logs. log4j was already used in the application
- OS or JRE specifc bugs but I guess I was lucky
- fact that I could have had to deploy the application on an already existing application server. I didn’t have so I was able to solve some of the issues by tuning the machine environment instead of changing the code
All these problems would have been mitigated if the code had come with:
- proper documentation
- automated tests (unit and/or functional)
Things to think about when transfering an application
- be sure that you’ve got the right version of the code
- be sure to limit yourselve to transferring the application as is on the new server. Don’t try to change any of the components version. That’s obvious but you’ve been warned.
- is the application documented ?
- does it come with tests?
- be sure to recognise the localisation settings: application, application server, VM, Operating System & preferences of the user running the application. That can be pretty messy. In fact, every application should dump as much information it has from its environment in the logs. Bare minimum are the system properties.
- try to avoid changing the code to solve problems. If you do, see if you can redeploy and test the updated application on the current production server. You don’t want to go from server1-locked-down-code to server2-locked-down-code
- be sure to not give an estimate before you have identified some of the potential problems listed above
update: it took me 10 days go make the migration + upgrade of some components. That includes things like setting up both my development workstation and the hosting server, documenting the installation and hosting config, fix the SQL install scripts (there were not up to date…), lose at least half a day due to the MySQL Ubuntu issue, learn the code sufficiently to identify the various problems, clean the DB from dirty data, add foreign keys to the DB, make a script to import the old DB backup onto the new server automatically (as the production server is still the old one, and we are in test phase), then upgrade various components on the new server (DB and DB driver, J2EE server, quartz version)… Upgrade has been smooth once the DB dirty state has been cleaned. I also implemented some automated tests using selenium during 2-3 hours, but that cover only a little part of the application. My (optimistic) goal was to use 5 days for it max.