Building and running the jar

Spring Boot · Essentials · 8 min

You need a fast dev loop and a deployable artifact.

The Spring Boot build plugin does two jobs. During development, ./mvnw spring-boot:run (or ./gradlew bootRun) starts the app from source. For deployment, ./mvnw package (or ./gradlew bootJar) produces an executable fat jar in target/ that contains your classes, all dependency jars and a small launcher, runnable anywhere with a JVM: java -jar target/shop-0.0.1-SNAPSHOT.jar.

Use the wrapper scripts (mvnw, gradlew) that Initializr generates, so everyone builds with the same tool version.

DevTools (spring-boot-devtools, a development-only dependency) restarts the application automatically when classes change on the classpath, which is much faster than a cold start, and disables template caching. It is excluded from packaged jars automatically.

For containers, ./mvnw spring-boot:build-image builds an OCI image with Cloud Native Buildpacks, no Dockerfile required. If you write your own Dockerfile, extract the jar into layers (java -Djarmode=tools -jar app.jar extract --layers) so dependency layers are cached between builds.

At startup the log shows the active profiles, the port and the startup time, and --debug prints the auto-configuration report, useful when something isn't configured the way you expect.

Example

# development
./mvnw spring-boot:run                      # or: ./gradlew bootRun

# package an executable jar and run it
./mvnw clean package
java -jar target/shop-0.0.1-SNAPSHOT.jar --server.port=9090

# container image via buildpacks (needs Docker)
./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=shop:latest
docker run -p 8080:8080 shop:latest

# see why things were (not) auto-configured
java -jar target/shop-0.0.1-SNAPSHOT.jar --debug | grep -A3 "Positive matches"

Remember

  • spring-boot:run/bootRun for development, package/bootJar for a fat jar
  • The fat jar runs anywhere with java -jar
  • DevTools restarts on change and is dropped from production jars
  • build-image creates a container image without a Dockerfile

Watch out for

  • Deploying the plain (non-repackaged) jar, which lacks dependencies and fails with ClassNotFoundException.

Check yourself

  1. What makes the Spring Boot jar executable with java -jar?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.spring.io/spring-boot/maven-plugin/index.html