First steps of migrating from Java 8 to Java 11

Daniel Lobo
3 min readJun 5, 2019

--

Motivation

If you have a business application with Oracle JDK 8, it’s time for changes. Oracle stopped releasing public updates for JDK 8 since January 2019.

You have five options from now on:

· Stay with Oracle JDK 8 without receiving any updates, which is not recommended

· Pay to receive Oracle JDK 8 support from Oracle

· Move from Oracle JDK 8 to an OpenJDK 8 distribution

· Migrate from Oracle JDK 8 to Oracle JDK 11, which has commercial use restrictions

· Migrate from Oracle JDK 8 to a free distribution of OpenJDK 11

If you decide to migrate to Java 11, be aware that Oracle JDK 11 has commercial restrictions. The alternative is to use a free distribution of OpenJDK 11 (Java is still free 😬).

The purpose of this article is to present you my personal experience from migrating an application from Java 8 to Java 11.

First Steps

Java Version

The first step is to change the java version in your pom file.

From:

<java.version>1.8 </java.version>

To

<java.version>11 </java.version>

If you enter the java version ‘1.11’, you are selecting the Java 1 version, and you will probably see a lot of compilation problems. We don’t want to downgrade our application to Java 1, right? 😄

Maven Compiler

I was using an incompatible Maven Plugin Version: 3.6.1. So, I had to upgrade it to a new version: 3.8.1.

From

<groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version>

To

<groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version>

I’ve read in some articles that any 3.7+ version will work, but I decided to use the newest version 3.8.1.

Spring Boot and Spring Cloud

Java 11 is not supported in Spring Boot 2.0.X and older versions, so I had to upgrade my Spring Boot to 2.1.5.RELEASE. As I use Spring Cloud as well, I had to upgrade it to a compatible spring cloud version: the Greenwich version (Greenwhich.RELEASE).

So, in my dependencyManagement I came up with:

<groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.1.5.RELEASE</version>

And

<groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Greenwich.RELEASE</version>

Migrating Spring Boot causes some extra work which I can write in another article. In my personal experience, I had some compilation problems with my repositories as I had to return Optional<MyObject> in some methods, which is good as I make my application more Null Point Safe by using the isPresent method.

If you don’t use Spring Boot …

You may upgrade your Lombok version to 1.18.8. I was using 1.16 and I had problems with it.

Add the javax.xml dependencies if you use it.

<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version></dependency>
<dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-core</artifactId><version>2.3.0</version></dependency>
<dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.3.0</version></dependency>

Javax.xml was deprecated in Java 9, and removed in Java 11.

Docker

We were using a container with an Alpine version installed running OpenJDK8.

FROM openjdk:8-jre-alpine

I wasn’t able to find by the moment I wrote this article an image with openjdk 11 and Alpine. The alternative to continue using Alpine was to use an image from Azul.

FROM azul/zulu-openjdk-alpine:11

Zulu is an openjdk distribution from Azul.

However, you can still use openjdk 11 image with Debian, if you want.

Even though Debian is more popular than Alpine we’ve chosen Alpine mainly because it has a shorter image size.

Wiremock

While upgrading the Wiremock module I had some issues with @PostConstruct and @PreDestroy.

These annotations weren’t available, so I had to implement InitializingBean and DisposableBean and override the following methods:

afterPropertiesSet and destroy.

So I went from:

public class WireMockConfig {@PostConstructpublic void init() {}@PreDestroypublic void destroy() {}}

To

public class WireMockConfig implements InitializingBean, DisposableBean {@Overridepublic void afterPropertiesSet() throws Exception {..}@Overridepublic void destroy() throws Exception {}

Conclusion

Thank you for reading this article. I hope I could help you in this migration process somehow. You will probably find other problems that I didn’t mention; feel free to comment your findings here, this way you can share your knowledge with us.

Daniel Lobo
Java Developer at Venturus
https://www.linkedin.com/in/danielpllobo/

--

--