,

Using CircleCI to Build Spring Boot Microservices

Introduction

I’m quickly becoming a fan of using CircleCI for CI builds. I’m finding that CircleCI is a very powerful platform. Recently, I configured CircleCI to build a Spring Boot Microservice. The microservice was generated by JHipster.

CircleCI is a online resource which uses Docker containers to run your CI builds. Since your build is running inside a Docker container, you can customize the container to support numerous different scenarios.

In this post, we’ll look at configuring CircleCI to build a Spring Boot Microservice generated by JHipster

Using CircleCI

CircleCI Account

CircleCI has a free tier which you can use for your CI builds. The free tier is limited to one running container at a time. Which is fine for many situations.

Signing up for CircleCI is crazy easy. All you need is a GitHub, BitBucket, or Google account.

Click here to get your free account.

Configuring CircleCI to Build JHipster Projects

JHipster Microservice

In this example, I’m using a Spring Boot microservice generated by JHipster.

My example application is a VERY basic example. I have not added any domains.

The focus of this post is on CI builds, not building microservices.

You can get the complete source code for this blog post here on GitHub.

CircleCI Build Config File

To build your project, CircleCI will look in the project root for the directory .circleci. The CircleCI build file is a YAML file named config.yml .

CircleCI has very powerful build capabilities. I cannot cove everything in this post. But, you can Click here to explore the capabilities found in CircleCI 2.0.

As Spring Framework Developers, it’s likely we will be using Maven or Gradle for our build tools. (I hope none of you are using Ant!)

Below are example build files for Maven and Gradle provided by CircleCI.

Maven CircleCI config.yml Example

Gradle CircleCI config.yml Example

Installing NodeJS

If your JHipster project has a UI component, you will need to install NodeJS and Yarn for the build process.

Adding these commands to the ‘steps’ section of your CircleCI build configuration will install NodeJS into the docker container running your build.

Installing Yarn

JHipster also uses Yarn for dependency management of UI components.

You can install Yarn by adding the following steps to your CircleCI build configuration.

Custom Docker Images

CircleCI does provide a number of pre-built images you can use for your builds.

In this example, I’m using an image with Java pre-installed.

It does not have NodeJS or Yarn pre-installed.

Above, I’m showing you how to install NodeJS and Yarn into your build container.

If I needed to build a lot of JHipster projects, I probably would develop my own custom Docker image for the builds.

In my custom image, I would pre-install NodeJS and Yarn.

Comment below if you would like to see a future blog post on how to setup a custom Docker image like this!

Building A Docker Image with CircleCI

You can also use CircleCI to build docker images to hold your Spring Boot microservice.

Of course, JHipster out of the box gives us the tools to build the Docker image.

CircleCI gives us the ability to leverage a remote Docker service to support Docker commands from within our build container.

To build a Docker Image of our Spring Boot microservice, we need to add two steps to our build configuration.

  1. Setup the Remote Docker connection to our build container.
  2. Run the build command for Maven / Gradle to build the Docker Image.

Here is an example configuration for using Gradle to create the Docker Image:

Complete CircleCI Build File

Here is the complete CircleCI Build file for my Spring Boot Microservice.

.circleci/config.yml

Memory Errors in CircleCI

In setting up some of my builds for JHipster, I ran into a intermittent build failures.

Here is the error I was seeing:

The exit value of 137 indicates the Java process was getting terminated by the operating system. Effectively the JVM was consuming too much memory. Then Docker was killing the container.

Some builds would work, some would fail.

I worked on this issue several hours and learned a lot about Gradle and JVM memory management.

Gradle Daemon for CI Builds

For CI Builds, the Gradle team recommends disabling the Gradle daemon. You can do this as follows:

gradle.properites

JVM Memory Settings

You can also configure JVM memory settings via the Gradle properties file.

The above configuration did not help me.

Gradle seems to be launching another JVM process to execute tests in, and that JVM process does not seem to honor the memory arguments set in org.gradle.jvmargs or via environment variables.

However, what did work for me, was to configure the test task via build.gradle.

I added the following to the build configuration generated by JHipster:

build.gradle

Note: MaxPermSize has been deprecated from Java 8 and above. See this link.

Once I limited the JVM memory consumption, my builds became stable.

The JVM was likely failing due to how Java works with Docker. The JVM ‘sees’ memory for the entire host system, and does not recognize the memory limitations of the Docker container. See this post for additional details.

This issue is going to get better in future releases of Java. It has been addressed in Java 9 and backported to Java 8.

 

Share

Leave a Reply