A few weeks ago, I’ve posted a blog about moving from Java EE 5 to 7. It was mostly about how you could improve your Java EE 5 code with the new Java EE 7 stuff. Now in this post, I’m going to look a little bit into the migration path on the Application Server side.
If you’re using Java EE 5, there is good chance that you are using one of these servers:
There are many other servers supporting Java EE 5, and you could check them out here.
I’ve ended up getting most of my experience with JBoss 4x, since the company I was working on at the time was already using it heavily in most of their projects. I hardly had any vote on the matter and just kept the company direction with JBoss.
When we decided to move one of our client critical applications from Java EE 5 to 7, we were faced with the dilemma of which application server to use. Since I was in a technical management position, I was now able to influence that decision. We end up picking Wildfly for the following reasons:
- Implemented Java EE 7 Full profile
- Powerful CLI to manage the server
- Team already familiar with the Java EE implementations shipped with Wildfly
Even though this post looks into JBoss and Wildfly, some of the principles still apply for Application Servers in general. So I hope that this can be useful for other Application Servers users as well. We are currently using Wildfly 8.2.0, but the content discussed in this post should also work with the latest Wildfly version.
Performing an Application Server migration, especially one that involves servers so far apart, is never easy. The migration path is not exactly straightforward, because each application ends up using different features of the Application Server. Worse, the application might even be implementing business code supported in these features that might not be available in the target migration server.
Anyway, there are two strategies that you can follow when working on a migration project:
As the name implies, you freeze your project to perform the necessary adjustments to migrate the application. It’s probably easier to deal with complexity, but on the other hand it delays business features and creates a non negotiable deadline. It’s very hard to convince stakeholders to go with this strategy, but if you are able, go for it.
The other alternative is to keep development going and work the migration at the same time. It’s best for the business, but requires much more discipline and planning. You can always partition and split your application into modules and migrate it in small bits. This in the strategy I usually use.
You might need some time to completely migrate your application. During that time, you need to keep the old server running as well as the new. For this, you are required to update and duplicate your environments. It’s like branching the code, but in runtime.
Support tools that you use, might need updating as well. Maven plugins for the new server, Jenkins deployments, whatever interacts with the Application Server. It’s a daunting task, since the complexity to manage all these extra environment and branches is not easy.
Walking the Path
There are a couple of details that you need to worry about when thinking about the migration. This is not an extensive list, but are probably the most common topics that you are going to come across.
If you don’t run into
ClassCastException you might want to consider to play the lottery and win!
This is especially true with JBoss 4.x Classloader. At the time, class loading was (still is, but even more than) an expensive operation, so JBoss used something called the
UnifiedClassLoader. This meant that there was no true isolation between applications. EAR archives could look into each other to load libraries. Of course, this was a major headache to manage. The worst part was when you had to deploy your application into a customer using a JBoss server. If you didn’t have control over it, the current deployment could clash with your own.
Wildfly introduced class loading based on modules instead of the usual hierarchical approach. Usually, an application deployed in Wildfly, doesn’t have access to the Application Server libraries unless is stated explicitly with a file descriptor. For Java EE Applications these modules are loaded automatically.
When changing servers, these are the most common issues related to class loading:
- Missing libraries that were sitting on other applications.
- Relaying on libraries sitting on the server that were either removed or updated.
- Libraries used on the application that are now part of the new server.
To fix this you need to tune your project dependencies by adding your removing the required libraries. There is no step by step guide here. Each case needs to be analyzed and fixed accordingly. It’s kinda like trying to untangle a string full of knots.
If you’re using