DEV Community

Mitz
Mitz

Posted on

Spring Boot Thin Launcher and Docker

Spring Boot Thin Launcher

Yesterday, I played with the Spring Boot Startup Bench.

and noticed it uses Spring Boot Thin Launcher. So today, I played with the Thin Launcher, which enables to create a thin jar.

https://github.com/dsyer/spring-boot-thin-launcher

My Source Code

is here:

https://github.com/bufferings/spring-boot-thin-sandbox

There are 3 directories.

  • demo-fat: Normal SpringBoot app.
  • demo-thin: Thin app.
  • demo-thin-docker: Thin app with docker.

demo-fat

This is just a simple spring boot app with web, though it has no page.

cd demo-fat
❯ ./mvnw clean package
❯ ls -ahl target/demo-fat-0.0.1-SNAPSHOT.jar
-rw-rw-r - 1 bufferings bufferings 16M Sep 30 22:16 target/demo-fat-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode

The size is 16MB.

❯ java -jar target/demo-fat-0.0.1-SNAPSHOT.jar
…
2018–09–30 22:29:04.617 INFO 32639 - - [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.852 seconds (JVM running for 4.464)
Enter fullscreen mode Exit fullscreen mode

demo-thin

This is also a simple spring boot app, but with Spring Boot Thin Launcher.

cd demo-thin
❯ ./mvnw clean package
❯ ls -ahl target/demo-thin-0.0.1-SNAPSHOT.jar
-rw-rw-r - 1 bufferings bufferings 11K Sep 30 22:24 target/demo-thin-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode

It's only 11KB. It downloads a launcher and libraries on startup, but actually it uses .m2 directory so it doesn't take so long.

❯ java -jar target/demo-thin-0.0.1-SNAPSHOT.jar
…
2018–09–30 22:30:51.689 INFO 1303 - - [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.012 seconds (JVM running for 4.987)
Enter fullscreen mode Exit fullscreen mode

demo-thin-docker

This is a thin app with Docker.

cd demo-thin-docker
❯ ./mvnw clean package
❯ docker build -t demo-thin-docker .
Enter fullscreen mode Exit fullscreen mode

This takes time to download all the dependencies.

❯ docker run -p 8080:8080 demo-thin-docker - thin.debug=true - thin.offline=true
…
2018–09–30 13:42:32.978 INFO 1 - - [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.437 seconds (JVM running for 5.804)
Enter fullscreen mode Exit fullscreen mode

The Dockerfile

is as follows:

FROM openjdk:11-jdk-slim
COPY docker/spring-boot-thin-wrapper-1.0.15.RELEASE.jar /thin/wrapper.jar
COPY pom.xml /thin/pom.xml
WORKDIR /thin
RUN jar cvf pom.jar pom.xml
RUN java -jar wrapper.jar \
     --thin.archive=/thin/pom.jar \
     --thin.dryrun=true \
     --thin.debug=true

FROM openjdk:11-jre-slim
COPY --from=0 /root/.m2 /root/.m2
COPY target/demo-thin-docker-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Enter fullscreen mode Exit fullscreen mode

FROM

FROM openjdk:11-jdk-slim
Enter fullscreen mode Exit fullscreen mode

There's no reason to use Java 11, we can use the older version :)

COPY wrapper.jar

COPY docker/spring-boot-thin-wrapper-1.0.15.RELEASE.jar /thin/wrapper.jar
Enter fullscreen mode Exit fullscreen mode

I wanted to create a docker layer for the libraries. So I downloaded the wrapper.jar and put it in the repository.

It has a feature of dry-run which doesn't run the main class but just download the libraries into .m2 repository.

COPY pom.xml

COPY pom.xml /thin/pom.xml
WORKDIR /thin
RUN jar cvf pom.jar pom.xml
Enter fullscreen mode Exit fullscreen mode

To create the docker layer, copy the project pom.xml. The wrapper.jar can load a pom.xml in jar file. So I create a jar file which has only the pom file.

dry-run

RUN java -jar wrapper.jar \
     --thin.archive=/thin/pom.jar \
     --thin.dryrun=true \
     --thin.debug=true
Enter fullscreen mode Exit fullscreen mode

Then, execute wrapper jar with the pom.jar in a dry-run mode. If you want to know more detail, you can set --thin.trace=true.

Then all the dependencies of the pom.xml are downloaded into the /root/.m2 directory.

COPY .m2

FROM openjdk:11-jre-slim
COPY --from=0 /root/.m2 /root/.m2
Enter fullscreen mode Exit fullscreen mode

I used the multi stage build, because I don't need other files except for .m2 . So I copied the .m2 directory into the new image.

COPY app.jar and run

COPY target/demo-thin-docker-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Enter fullscreen mode Exit fullscreen mode

Then as usual, copy the jar and run it.

Offline Mode

To check there's no download on runtime, I used the - thin.offline=true to run docker with offline mode.

❯ docker run -p 8080:8080 demo-thin-docker - thin.debug=true - thin.offline=true
Enter fullscreen mode Exit fullscreen mode

The good parts with docker

As long as we don't change the dependencies, the library layer is reused. So the build finishes in no time.

That's all for today's fun. And I'm thinking what kind of usage fits to Thin Jar and Fat Jar.

Top comments (0)