Micronaut® Blog

What's new for Maven users in Micronaut 2.2

By Álvaro Sánchez-Mariscal

November 23, 2020

Tags: #maven #docker #graalvm

The Micronaut 2.2 release includes version 1.1 of the Micronaut Maven Plugin. This new version of the Maven plugin includes the ability to package a Micronaut application into different formats (fat JAR, native image, Docker, etc), generating Dockerfiles, as well as pushing Docker images to different registries.

mvn package all the things!

There are already Maven plugins out there to produce Docker or native images, and we could have just updated our documentation explaining how to use their different goals. However, we thought we could do a better job, and starting with Micronaut 2.2, mvn package is your one-stop shop for packaging your application into different formats.

The way this works is via a custom lifecycle for the package phase in which we cherry-pick what plugins/goals participate to produce the resulting artifact. Also, where existing plugins didn't suffice, we implemented our own goals and added them to the lifecycle so that mvn package just works for all cases. The configuration of these plugins is defined in either the Micronaut Parent POM, or the application POM generated by Micronaut Launch.

To determine the packaging type, you use the <packaging> tag in your POM. By default, it is defined as <packaging>${packaging}</packaging>, with a property named packaging set to jar by default. Therefore, mvn package will produce a fat JAR by default, as it was the case before. The supported packaging types are:

  • jar (default): produces a runnable fat JAR.
  • native-image: generates a GraalVM native image.
  • docker: builds a Docker image with the application artifacts (compiled classes, resources, dependencies, etc).
  • docker-native: builds a Docker image with a GraalVM native image inside.

For example, to generate a GraalVM native image, you can simply run:

$ ./mvnw package -Dpackaging=native-image

To build a Docker image, you can choose between docker and docker-native, depending on whether the application is executed as either JVM or native image, respectively. The Micronaut Maven Plugin uses internally Jib where possible, or a raw Docker client otherwise, to build the images.

Also, if you prefer, you can generate the equivalent Dockerfile and customise it to your needs:

$ ./mvnw mn:dockerfile -Dpackaging=docker-native

If you grab the generated Dockerfile, make the modifications you want, and place it at the project's root, mvn package will use it for subsequent Docker builds.

Check the Micronaut Maven Plugin packaging documentation for more information about the supported options.

Pushing Docker images to Docker registries

The Docker packaging options shown above will build and tag images to the local Docker daemon. If you want to push them to remote registries, you can use mvn deploy. The supported packaging types are:

  • jar (default): will deploy the JAR artifact to a remote repository delegating to the org.apache.maven.plugins:maven-deploy-plugin:deploy goal, as it was the case before.
  • docker or docker-native: will push the Docker image to the configured Docker registry by leveraging the Jib plugin configuration.

For example, to push an image to Docker Hub:

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <configuration>
    <to>
      <image>docker.io/my-company/my-app:${project.version}</image>
    </to>
  </configuration>
</plugin>

Then, you can execute mvn deploy -Dpackaging=docker or mvn deploy -Dpackaging=docker-native. The Micronaut Maven Plugin will do a best-effort attempt to honour credentials defined at ~/.docker/config.json, as well as using credential helpers such as docker-credential-gcr for Google Cloud’s gcr.io and docker-credential-ecr-login for Amazon’s ECR. Other credential helpers, or even username/password authentication can be defined via the Jib plugin configuration.

Check the Micronaut Maven Plugin deploy documentation for more information about the supported options.

The future ahead

This is just the beginning of new awesomeness that will land into the Micronaut Maven Plugin. The next step is to move both the Maven and Gradle plugins to the same Git repository and have them share code so that they have the same features. We hope to have this ready by Micronaut 2.3.

In the meantime, feel free to report issues if you find them, or feature requests, in the Micronaut Maven Plugin issue tracker. We hope you enjoy this new version!