First MicroProfile.io application using Java Module System

Embrace the JPMS power with MicroProfile.io applications

Update

Sample application migrated to use JDK 11.

MicroProfile.io

Eclipse MicroProfile project is growing fast, it has a lot of supporters and compatible implementations.

I see it as a new way to package enterprise Java Enterprise applications that already leverage of existing Java Specifications (JSRs) and want to be compatible with different platforms, specially ready for running in Cloud.

It also aims to reduce the gap between community feedback and release of new features.

I would like to mention that in addition of well know MicroProfile implementations like Payara Micro, WildFly Swarm, TomEE and Websphere Liberty, there's also Hammock, which I'll use in this post.

Hammock is an open-source project that allows the creation of CDI based microservices using Microprofile.io specification and additional starter modules such as JPA (Hibernate/EclipseLink/OpenJPA), Security (JWT, Keycloak), Messaging (Artemis/RabbitMQ) or your own starter module, just like Spring Boot does, but in a CDI way.

Currently in development version 2.2 supports most of MicroProfile.io 1.3 capabilities.

First MicroProfile.io JPMS application

There're few ways to start using Hammock, the easiest one is to add the following maven dependency.

Personally, as I want to ensure my application dependencies are thin I prefer to use the DIY way, adding each module individually (CDI, REST, JSON), so I can choose which implementation of CDI, REST and JSON I’ll use.

It also helps us to fix JPMS comparability issues that I found during the implementation of (my) first MicroProfile.io JPMS application (I have not heard of any other on the internet).

As usual, I already explained in previous post Upgrade to Java 10 now! Why not? in which I only add module-info.java and deal with application dependencies to start using module system.

The problem

Java Module System (JPMS) is still recent and thirdparty libraries and frameworks are trying to catch up to support modularization, so we will need a few tweaks, like preventing two JARs with the same package names conflicts in the classpath (that was already a hidden problem, because you know, API changes and first class on classpath wins).

With JPMS, it prevents two modules (or automatic modules) to export the same package.

Solution

The sample application is a basic Hello World JAX-RS resource using JSON-B.

With the following module descriptor:

View the Maven project descriptor (pom.xml) to see the dependencies and plugins declarations.

Results

The total size of this example application is around 12mb and the startup time of the whole application is around 1s in my machine.

Also the maximum memory usage (RSS) of the JVM was 133mb in my tests.

Note: The maximum heap size used in tests was -Xmx128m.

Put Things Together using JLink and Docker

Following the same approach of previous post Create a Cloud Native Image using Java Modules I can create a minimal JVM to run the application and generate a Docker image.

The resulting was an amazing 54.3mb Docker image with only minimal JRE and application modules.

If you look carefully, you will notice that a patch-module was added in the command line in order to hack JPMS and remove java.desktop module dependency. We really don't need Swing/AWT classes here!

I was only able to achieve that using my new pet project LiteBeans, a java.beans package patch and alternative API implementation used to remove java.desktop module requirement on JDK 9 and up.

Conclusion

The CDI is the new glue and Docker the new hammer.

Finally, you can find the source in this repository: panga/hammock-jpms

Also the instructions to build and run are available in the README.