DEV Community

Mariela Dimitrova for Software AG Tech Community

Posted on • Originally published at tech.forums.softwareag.com on

Migrate Java microservices from Java 8 to Java 11

Some people might have struggled to efficiently migrate their Java microservices from 8 to 11+.

There are 2 main reasons you’d want to do that:

  • Java 8 end of line coming soon ;
  • Java 9+ modules that help build “slimmer” JVM.

Now, if you simply switch from Java 8 to Java 11 you’ll end up with microservices that will be 50% bigger in size and resource consumption, if you use the Maven plugin to build your microservice, that is. Not really slim…

Why is that? Actually the Maven plugin uses a default Dockerfile that will install the full JDK, whatever the version of Java you’re using. Meaning if you use Java 9+, you’ll end up with a docker image that contains all the java modules, even those that you don’t need…

You’re going to need a custom Dockerfile to take full advantage of the modules system of Java 11 that’ll use jlink to build a custom JVM that will include only the modules you need.

Here’s a sample dockerfile, that should fit for almost everyone (just change the project name in the COPY command):

FROM alpine:3 as base
RUN apk add --no-cache openjdk11
RUN jlink \
--module-path /opt/java/jmods \
--compress=2 \
--add-modules java.se,jdk.unsupported \
--no-header-files \
--no-man-pages \
--output /opt/jdk-mini
FROM alpine:3
COPY --from=base /opt/jdk-mini /opt/jdk-mini
RUN apk add --no-cache coreutils
ENV JAVA_HOME=/opt/jdk-mini
ENV PATH="$PATH:$JAVA_HOME/bin"
COPY etc/ /etc/<your project name goes here>/
ADD resources/* /data/
RUN chmod +x /data/entrypoint.sh
ENTRYPOINT /data/entrypoint.sh

Enter fullscreen mode Exit fullscreen mode

Next question is: where to put this Dockerfile so that the Maven plugin will use it instead of the default one?

Pretty easy: just put it in src/main/docker/Dockerfile.

That’s it!

Regarding the dependencies: why java.se and jdk.unsupported?

That’s because of Spring (and Spring Boot) which is a hard dependency of Cumulocity Java SDK.

Spring depends on java.beans, which requires java.desktop, which itself includes… java.awt. And many other dependencies are also required. In the end including java.se is simpler and doesn’t cost much (maybe 1 or 2 MB compared to a better filtered JVM).

jdk.unsupported is also required by Spring.

Hope that will help!

If you want more info regarding java modules and how to use them efficiently, here’s a great Devoxx UK session on Youtube (this helped me figure out that I needed jdk.unsupported module):

There’s also an interesting dicussion regarding Spring dependencies on java.desktop: Remove dependency on java.desktop and other modules · Issue #26884 · spring-projects/spring-framework · GitHub

Hopefully Spring 6 might change that…

Read full topic

Top comments (0)