Generally, most companies avoid migrations. That's mostly because they often don't offer any clear and instant advantages, while the risk is substantial. Also, developers performing migration are blocked from delivering value to the customers. It has become increasingly complicated to perform the migration. In this article, we will focus on migrating from Java 8 to the newest version since it's still the most popular one in the world of developers.
Oracle - the creators of the Java language - have changed their release policy. Now one "small" release is scheduled every six months, rather than having a "big" one released every 3 years. According to Mark Reinhold, the Chief Architect of Java Platform, that's because Java needs to be more competitive compared to other platforms that evolve faster.
It may sound like bad news for companies that want to be up to date with the newest version of this programming language. That may require more migrations than before. However, smaller changes aren't so difficult to introduce, and the process becomes less and less laborious after some 2 or 3 migrations.
Benefits from migrating to Java 13
In the beginning, let's take a closer look at the advantages of migrating to a newer version of Java. Previously, the introduction of lambdas and functional programming in Java 8 was a massive change that created a revolution in the Java code. Subsequent releases didn't bring similar changes, however, there are still some handy features that are worth mentioning - and considering to use after migration. I would especially point to:
- Better API for the Optional class that makes it easier to use.
- Improvements in Predicate classes to allow making Predicates chains easier.
- Some convenience factory methods for collections - especially for creating collections.
- Ability to collect unmodifiable collections from streams.
- Introducing of JShell - the REPL that allows running some individual lines of code. It's very useful when we test code quickly.
- Embedded HttpClient - most applications use HTTP today, and developers were previously forced to use third-party libraries.
- JLink, which is a fantastic tool to package and deploy only the selections of JDK that are necessary for deployment.
- Text blocks - very helpful when working with big multiline strings.
- Reimplementation of the legacy socket API.
The secondary benefit is better performance. Generally, every release performs better than the previous one. We can observe improvements in startup time, memory consumption, and fewer CPU cycles. Also, some significant changes in memory management were introduced, like improvements in GC. All of these improvements can bring some significant code reduction because of smaller artifact size and a decrease in cloud computing power and costs.
The last benefit that I want to highlight is more organizational rather than technological. In general, ambitious developers want to improve their skills and develop professionally at their company. It may be hard to improve their skills when using some legacy, outdated codebase. Using an outdated version of JDK could discourage many talented developers from joining your company - while having the newest version can encourage them to become part of your team.
Migration to Java 13 step by step
Compilation warnings look rather harmless and are often ignored by developers because the project is already compiled, so why bother? However, before migrating to a newer version of JDK, it's a good idea to address most of the compiler warnings. Usually, they're about some deprecated methods that have eventually disappeared in the newest version of Java. It's worth solving them before use a newer version of JDK to compile the project.
Second, you should check for usages on the internal APIs that were hidden, starting from Java 9. This may require some significant changes in your codebase if you are using classes from sun.misc.* package. There is a very useful tool called jdeps that will scan your codebase and generate a report on whether and where you use internal APIs, also with some hints on how to solve found issues. It's also a good occasion to check if our application performs operations that are not safe.
The next step is upgrading your build tool and compiler level. If you are using Maven, then you need to use the newest version of the Maven plugin (3.8.1 for now). Configure it to support Java 13 and provide the following configuration:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>13</source> <target>13</target> </configuration> </plugin>
For Gradle you need to use the plugin in version 6.0 or above. It should be release soon (mid October 2019). You have to adjust the configuration of the source and target compatibility version as follow:
sourceCompatibility = JavaVersion.VERSION_13 targetCompatibility = JavaVersion.VERSION_13
Also, you may face some issues while migrating to a higher version of Java due to the fact that most libraries and frameworks use the reflection or internal API to fulfill their functionalities. The use of the internal API is not possible. Most libraries already support Java 9+, and so you need to make sure that your libraries are up to date. Unfortunately, some libraries will have to be replaced. So you need to carefully check all your dependencies and see whether they are working correctly. It might sound harsh, but there is some good news as well - it's a one time job, and repeating it won't be necessary for further releases.
In this article, we wanted to encourage you to make a quick migration once the new version of JDK is released. Your company will gain some substantial benefits, and consecutive migrations will go smoother. At Solidstudio Software House, we performed a migration to the new version of JDK for our projects 2-3 months after the JDK's release. It took us several person-days, but we believe that we have gained a substantial benefit - and that it's worth performing that operation on a regular basis.