In many companies, migration to new technologies is a taboo topic. The management would rather avoid it, and developers often complain about outdated stack between each other. That situation usually lasts for a long time, and no one wants to change anything, especially if the project is live and profitable. In that case, the decision to perform a migration looks like an unnecessary risk.
In my previous article
, I offered a guideline to migrate from Java 8 to 13. In this article, I will focus on the migration from Java 7 since the differences between Java 7 and 8 are much more significant than between 8 and 13.
I will start to elaborate on why migration from Java
7 is extremely important, and you should not postpone it anymore.
Reasons to migrate from Java 7
Compatibility with modern frameworks
There were significant changes between Java 7 and its further versions. Besides some "standard" changes like optimized performance or extending some existing API, it includes changes in the syntax itself.
This means that Java
8 is no longer forward compatible. Long story short, the code written in the newer version may not work on the previous version. This also means that the whole further Java ecosystem will not work with Java 7.
Also, it means that most libraries that support Java 8 will no longer work with previous versions. This includes some frameworks required to build modern, enterprise applications like Spring
. Since the frameworks evolve and modern solutions for new problems emerge, it's become one of the main reasons why you should consider a migration.
The second important reason is developers' performance. The new Java features bring huge changes in collection processing, and since it's one of the most common problems, developers need to handle it to significantly boost their performance. Also, other improvements like Optional make code less error-prone.
What's more, talented developers usually want to work with the newest technologies. So, if your project has a legacy stack, it makes you a less attractive employee. At some point, it will be quite unlikely to get good people from the market. Losing good people is usually the beginning of a much bigger problem that could eventually lead to the death of your project. So you need to act now!
Better performance and security
Each new version of Java brings some optimization and security fixes. It is not visible at first glance, but it will help you to boost the performance and security of your application.
So here are some other benefits that come with bumping the language version:
- Performance - each newer Java version optimizes the memory management in terms of Garbage Collector, also CPU operations are more and more optimal.
- Security - Oracle advises moving from Java 7 to avoid security risks.
- Older releases are not supported anymore.
Why do companies put away migration?
Even though migrating to a newer Java version is a smart move, companies, especially the big ones, postpone migration and leave legacy projects. I will try to explain why.
The project is really big and fragile
When the project is very big and has an enormous number of dependencies on external and internal libraries, it may be extremely difficult to perform the migration. So, even having all the benefits in mind, the risk is too high, and no one wants to make the call to migrate. Business people don't want to touch the existing solution - at least it's working. Later on, in this article, we will provide guidelines that can be used even in some tough cases.
Pressure to implement a new feature
In many cases, there is pressure from clients to implement new features as soon as possible, and usually, that's a priority over improving the existing codebase. That's probably one of the hardest cases since convincing clients might be pretty hard. You need to use very convincing data and explain how it may be valuable to him. But that's a huge topic, and I'm not going to get into it in this article.
Sticking to the status quo
Having difficulties with the client or an enormous codebase may be a justified reason to avoid migration. But here's the problem: a lot of companies don't think about migration even during a quiet time when developers have some spare capacity and could easily spend some time performing the migration for future sake. Unfortunately, there is a massive tendency to stick to the status quo, especially during good times when clients are happy and we have some spare capacity and could migrate our application step by step. If your stack is "not so old" then it's really hard to motivate anyone to migrate from Java 8 to Java 9. But trust me, it's better to migrate one version than a bunch of versions at one time.
Migration from Java 7 step by step guideline
As I mentioned before, there are some major differences between Java 7 and later releases, and there is no forward compatibility. So besides upgrading the Java version, you need to update all of the related third-party libraries and frameworks. So basically, the migration plan should look like this.
- Know your libraries and framework.
- Upgrade libraries, adjust the codebase, and build a new version.
- Test as much as possible to make sure that it works as expected in the desired environment.
Know your libraries and frameworks
The first phase would be to analyze the current codebase and all of its dependencies. It's better to take a look at the big picture rather than blindly bump each library in the hope that it will start to work. It's worth reading the documentation of particular libraries to see which versions start to support your desired Java version.
So first, create a table with the following format. This is a good start for a migration plan.
LibraryCurrent versionTarget versionSpring Boot184.108.40.206
For example, Spring Boot 1.5.X supports Java up to version 7. Starting from version 2.0, Java 7 is no longer supported. So, if you want to migrate to Java 11 or above, you need to upgrade Spring Boot to version 2.1.
Bumping Spring Boot from 1.5.1 to 2.4 can be costly and will require some code and configuration changes, that's for sure. How costly this operation becomes will depend on the number of used libraries, but in general, upgrading most libraries to support Java 11 requires some substantial changes. Sometimes, you can find additional guidelines on official framework pages like Spring Boot that can be really helpful.
There are two differences between the class and the record from the example above.
This also applies to any tools that are used by the application like static code analyzers, code style checked, etc. If you are using SonarQube
, you also need to change its version so you can make use of it with the new Java version.
Build your application in the new Java version
So, after the initial analysis, you need to bump each library one-by-one and try to compile your project. Usually, it will require a change to the existing codebase to adjust it to the new API, because in such a version usually, API changes aren't compatible. Sometimes, it will be an easy change like the method name change, but other times you will need to dig into the documentation and write equivalent code using the new API.
By its nature, Java is backward compatible, so there should be no problem with compiling the existing codebase (other than changes in third-party libraries described above). However, there are some cases when compilation errors happen with Java 7 code. These are usually due to some unresolved compilation warning around generics. These errors are usually easy to fix.
If your code compiles correctly, then you need to run an automated test to see if it works as expected. Also, if possible, you should try to run the application locally to check if it goes up. There are some cases where, besides the code, you need to adjust your application configuration properties. That's the place where your IDE can become really handy and will mark all of the properties that are obsolete. Make sure that your IDE version is up to date.
Test as much as possible to make sure that it works as expected in the desired environment
If your application is working locally, you may deploy it to a new test environment. You need to prepare servers to be able to deploy the newer version. The test environment should mimic the production environment to avoid further unexpected errors. The most important part is the test behavior of the application.
You should have a bunch of automated tests for your services and the Web Application. The more tests you have, the more confidence you'll gain that's nothing broken. When your test suite doesn't cover all of the flows, then some additional manual tests are required. Ideally test all the possible flows to search for unexpected behavior or errors. It's not always possible to test the whole application manually because it can be very large. However, you should definitely check some sanity tests for all positive flows. In general, perform as many tests as possible to make sure that there is no problem with the new version, and it works as expected.
At this point, it's also worth mentioning that keeping your test suite up to date can help during the migration to newer versions. For instance, the contracts of REST services will not change during the migration, so tests will be valid after the migration, as well as the web application flow. So that's another reason to keep your test suite up to date as part of the development process.
At Solidstudio Software House
, we try to keep our tech stack up to date. We took advantage of writing tests as a part of the development process, and thanks to that, the migration process was smooth. If your project works on Java 7 or below, then you should definitely consider migrating to a newer version. I hope that this article helps you do that. Good luck!