Knowledge Base

Notice Information in this article applies to Excelsior JET version 15.3 and above. For versions 11.0 through 15.0, see article #38.

APPLICABILITY

The instructions laid out in this article were validated against Spring Boot 2.0.1 and Docker Engine 18.06.1-ce. They may not fully apply to other versions.

Excelsior JET, Enterprise Edition and Excelsior JET Embedded provide dedicated support for Spring Boot 1.4 and above. Native compilation of Spring Boot application using other Excelsior JET editions and versions is also possible and is covered in this article, though versions prior to 15.3 have weaker support for the Spring framework itself.

SUMMARY

Spring Boot is a framework that facilitates rapid development of Spring-based applications. It is often used to create microservices. The Spring Boot build process normally yields an "uberjar" that can be launched as a standalone application, but it is also possible to produce an executable war file that can be either launched as a standalone application or deployed to a servlet container.

This article provides instructions for compiling a Spring Boot application down to a native executable with Excelsior JET and containerizing it with Docker.

DETAILS

Native Compilation

If you are building your Spring Boot project using Maven or Gradle and the result is an executable jar or war file, then the easiest way to enable native compilation is via dedicated support for Spring Boot found in the respective Excelsior JET plugin: Excelsior JET Maven plugin or Excelsior JET Gradle plugin.

Note that dedicated support for Spring Boot is available only in Excelsior JET, Enterprise Edition and Excelsior JET Embedded. However, a Spring Boot application can also be launched as a plain Java SE application, if you list all its dependencies on the classpath instead of packaging them together with application classes into a single, self-contained executable jar. That means you can actually use any Excelsior JET version and edition to enable the native build, albeit with some extra efforts:

  1. If you have the Spring Boot Maven or Gradle plugin enabled in your pom.xml file or build.gradle script, you need to instruct it to not overwrite the application jar file produced by default. (That file contains only your application classes and not their dependencies). You can do that by setting the classifier Spring Boot plugin parameter so that your build will produce two jars, or simply disabling the Spring Boot plugin.

  2. Important: There is a slight chance that the behavior of your application will depend on whether it is packaged together with all dependencies into a single jar or not. Make sure to test your application built in this mode on a regular JVM before compiling it with Excelsior JET.

  3. Then you can use the Excelsior JET Maven or Gradle plugin with the appType parameter plugin "plain" and the mainClass parameter set to the name of the Spring Boot start class. You may also need to set the mainJar plugin parameter to refer to the jar file containing your application classes.

Containerizing With Docker

Create files Dockerfile and .dockerignore in the root directory of your project, replacing my-app-binary with the actual name of the native binary produced by Excelsior JET:

  • If using Maven:

    Dockerfile:

    FROM frolvlad/alpine-glibc:alpine-3.4
    COPY target/jet/app .
    CMD ./my-app-binary
    EXPOSE 8080

    .dockerignore:

    src/*
    target/*
    !target/jet/app
    pom.xml
    .git
    .gitignore
  • If using Gradle:

    Dockerfile:

    FROM frolvlad/alpine-glibc:alpine-3.4
    COPY build/jet/app .
    CMD ./my-app-binary
    EXPOSE 8080

    .dockerignore:

    .gradle
    build/*
    gradle
    src/*
    !build/jet/app
    build.gradle
    gradlew
    gradlew.build
    .git
    .gitignore

Important: If you are using a version control system other than Git, make sure to replace the last two lines of .dockerignore with patterns to exclude the respective files and directories.

Issue a docker build command to create a Docker image with the application:

docker build -t my-app .

To create a writeable container layer over the freshly created image and start it, issue the following command:

# Change port numbers in the `-p` option as necessary.
docker run -d --name my-service -p 8080:8080 my-app

To check whether the application has started successfully:

docker logs my-service

To stop the container:

docker-compose stop -t 1 my-service

For details, refer to the official Docker documentation.

REFERENCES

Article ID: 42
Last Revised On: 06-Nov-2018