
gradle-spring-boot-integration
by dawiddutoit
Collection of Claude Code skills, agents, and plugins
SKILL.md
name: gradle-spring-boot-integration description: | Integrate Gradle with Spring Boot projects, including plugin setup, bootable JAR creation, layered JARs for Docker, and multi-module Spring Boot configurations. Use when setting up Spring Boot builds, creating executable JARs, or configuring microservices with shared libraries.
Gradle Spring Boot Integration
Table of Contents
Purpose
Set up and configure Spring Boot projects in Gradle with proper JAR creation, Docker optimization, and multi-module support. This skill covers bootable JAR setup, layered JARs for optimal Docker caching, and Spring Boot-specific task configuration.
When to Use
Use this skill when you need to:
- Set up new Spring Boot projects with Gradle
- Create executable JAR files for Spring Boot applications
- Configure layered JARs for optimized Docker builds
- Set up multi-module projects with shared libraries
- Configure Spring Boot DevTools for hot reload
- Inject build information into application.yml
- Set up Spring Boot Actuator for monitoring
- Configure testing with Spring Boot test starters
Quick Start
Minimal Spring Boot setup in build.gradle.kts:
plugins {
id("java")
id("org.springframework.boot") version "3.5.5"
id("io.spring.dependency-management") version "1.1.7"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test {
useJUnitPlatform()
}
Run and build:
./gradlew bootRun # Run locally
./gradlew bootJar # Create executable JAR
./gradlew bootRun --args='--spring.profiles.active=dev' # Run with profile
Instructions
Step 1: Apply Spring Boot Plugin
Configure the Spring Boot Gradle plugin for your project type:
// build.gradle.kts - Web Service (creates bootable JAR)
plugins {
id("java")
id("org.springframework.boot") version "3.5.5"
id("io.spring.dependency-management") version "1.1.7"
}
Key plugins:
org.springframework.boot: Creates executable JARs, provides bootRun taskio.spring.dependency-management: Automatically imports Spring Boot BOM
Step 2: Configure Java Toolchain
Specify Java version for consistency:
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
Step 3: Add Spring Boot Dependencies
Use the BOM automatically imported by the plugin:
dependencies {
// Spring Boot starter (no version needed - from BOM)
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
// Development only (DevTools for hot reload)
developmentOnly("org.springframework.boot:spring-boot-devtools")
// Test dependencies
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
// Enable JUnit 5
tasks.test {
useJUnitPlatform()
}
Step 4: Configure Bootable JAR Creation
For services (executable JARs):
tasks.bootJar {
enabled = true
archiveClassifier = "" // No classifier for main artifact
}
tasks.jar {
enabled = false // Disable plain JAR
}
For libraries (plain JARs):
tasks.bootJar {
enabled = false // Not executable
}
tasks.jar {
enabled = true // Create library JAR
}
Step 5: Enable Layered JARs for Docker Optimization
Layered JARs separate dependencies by change frequency for better Docker caching:
tasks.bootJar {
enabled = true
layered {
enabled = true
application {
enabled = true
}
dependencies {
enabled = true
}
springBootLoader {
enabled = true
}
snapshot {
enabled = true
}
}
}
Layers (in order):
- dependencies: Rarely-changing external dependencies
- spring-boot-loader: Spring Boot loader classes
- snapshot-dependencies: Snapshot/SNAPSHOT versions (changing)
- application: Application classes (most frequently changing)
Extract layers in Dockerfile:
FROM eclipse-temurin:21-jre-alpine AS builder
WORKDIR /builder
COPY build/libs/app.jar .
RUN java -Djarmode=layertools -jar app.jar extract
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /builder/dependencies ./
COPY --from=builder /builder/spring-boot-loader ./
COPY --from=builder /builder/snapshot-dependencies ./
COPY --from=builder /builder/application ./
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
Step 6: Configure Application Properties
Inject build information into application.yml:
tasks.processResources {
filesMatching("application.yml") {
expand(
"version" to project.version,
"name" to project.name,
"timestamp" to System.currentTimeMillis()
)
}
}
In application.yml:
spring:
application:
name: ${name}
info:
app:
name: ${name}
version: ${version}
build-timestamp: ${timestamp}
Step 7: Set Up Spring Boot DevTools for Local Development
Enable hot reload during development:
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
Trigger reload:
- IntelliJ: Build Project (Cmd/Ctrl + F9)
- Eclipse: Save file
- CLI: Run
./gradlew compileJavain separate terminal
Step 8: Configure Actuator for Monitoring
Add actuator endpoints and metrics:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("io.micrometer:micrometer-registry-prometheus")
}
In application.yml:
management:
endpoints:
web:
exposure:
include: health,info,prometheus,metrics,env
metrics:
export:
prometheus:
enabled: true
endpoint:
health:
show-details: always
Examples
Example 1: Simple Web Service
// build.gradle.kts
plugins {
id("java")
id("org.springframework.boot") version "3.5.5"
id("io.spring.dependency-management") version "1.1.7"
}
group = "com.waitrose"
version = "1.0.0"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test {
useJUnitPlatform()
}
tasks.bootJar {
enabled = true
}
tasks.jar {
enabled = false
}
Build and run:
./gradlew bootJar # Create JAR: build/libs/app-1.0.0.jar
java -jar build/libs/app-1.0.0.jar # Run JAR
Example 2: Multi-Module with Shared Library
// settings.gradle.kts
rootProject.name = "supplier-charges"
include("shared-domain")
include("shared-api")
include("supplier-charges-hub")
// Root build.gradle.kts
plugins {
id("java") apply false
id("org.springframework.boot") version "3.5.5" apply false
id("io.spring.dependency-management") version "1.1.7" apply false
}
subprojects {
apply(plugin = "java")
apply(plugin = "io.spring.dependency-management")
group = "com.waitrose"
version = "1.0.0"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test {
useJUnitPlatform()
}
}
// shared-domain/build.gradle.kts
plugins {
id("java-library")
}
dependencies {
api("org.springframework.boot:spring-boot-starter-data-jpa")
}
// Library - create plain JAR
tasks.bootJar {
enabled = false
}
tasks.jar {
enabled = true
}
// supplier-charges-hub/build.gradle.kts
plugins {
id("org.springframework.boot")
}
dependencies {
implementation(project(":shared-domain"))
implementation(project(":shared-api"))
implementation("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
// Service - create bootable JAR
tasks.bootJar {
enabled = true
layered {
enabled = true
}
}
tasks.jar {
enabled = false
}
Build and test:
./gradlew clean build # Build all modules
./gradlew :supplier-charges-hub:bootJar # Build specific service
java -jar supplier-charges-hub/build/libs/supplier-charges-hub-1.0.0.jar
Example 3: Layered JAR with Dockerfile
build.gradle.kts:
tasks.bootJar {
enabled = true
layered {
enabled = true
}
}
Dockerfile:
# Multi-stage build using layered JAR
FROM eclipse-temurin:21-jre-alpine AS builder
WORKDIR /builder
COPY build/libs/supplier-charges-hub-1.0.0.jar app.jar
RUN java -Djarmode=layertools -jar app.jar extract
# Final image
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
# Copy layers (most frequently changed last)
COPY --from=builder /builder/dependencies ./
COPY --from=builder /builder/spring-boot-loader ./
COPY --from=builder /builder/snapshot-dependencies ./
COPY --from=builder /builder/application ./
# Non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# JVM configuration for containers
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Xms256m"
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
Build:
./gradlew bootJar
docker build -t supplier-charges-hub:1.0.0 .
docker run -p 8080:8080 supplier-charges-hub:1.0.0
Example 4: Application Properties with Build Info
build.gradle.kts:
tasks.processResources {
filesMatching("application.yml") {
expand(
"version" to project.version,
"name" to project.name,
"build.timestamp" to System.currentTimeMillis(),
"build.number" to System.getenv("BUILD_NUMBER") ?: "local"
)
}
}
src/main/resources/application.yml:
spring:
application:
name: ${name}
info:
app:
name: ${name}
version: ${version}
build-timestamp: ${build.timestamp}
build-number: ${build.number}
java:
version: '@java.version@'
compiler: '@java.compiler@'
Access via actuator:
curl http://localhost:8080/actuator/info
# {"app":{"name":"supplier-charges-hub","version":"1.0.0",...}}
Example 5: Testing Configuration
// build.gradle.kts
dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.testcontainers:testcontainers:1.21.0")
testImplementation("org.testcontainers:junit-jupiter:1.21.0")
testImplementation("org.testcontainers:postgresql:1.21.0")
}
tasks.test {
useJUnitPlatform()
// Test filtering
filter {
includeTestsMatching("*Test")
excludeTestsMatching("*IntegrationTest")
}
// Parallel test execution
maxParallelForks = Runtime.getRuntime().availableProcessors() / 2
// Test logging
testLogging {
events("passed", "skipped", "failed")
showExceptions = true
showStackTraces = true
showCauses = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}
Commands Reference
# === RUNNING ===
./gradlew bootRun # Run the app
./gradlew bootRun --args='--spring.profiles.active=dev' # With profile
# === BUILDING ===
./gradlew bootJar # Build executable JAR
./gradlew bootWar # Build executable WAR
./gradlew build # Build everything
# === TESTING ===
./gradlew test # Run unit tests
./gradlew test --tests "*IntegrationTest" # Run specific tests
# === INFORMATION ===
./gradlew bootRun --args='--help' # Show Spring Boot help
./gradlew properties # Show project properties
# === CLEANUP ===
./gradlew clean # Clean build outputs
Troubleshooting
DevTools hot reload not working:
- Ensure it's in
developmentOnlyconfiguration - Run
./gradlew compileJavato trigger reload - Check IDE auto-build settings
JAR not executable:
- Verify
bootJar.enabled = true - Check
java -jar build/libs/app.jar - Ensure main class is detected (usually automatic)
Missing dependencies in JAR:
- Check configuration: use
implementationnotcompileOnly - Verify BOM is imported correctly
- Run
./gradlew dependenciesto inspect tree
See Also
- gradle-dependency-management - Manage Spring Boot BOMs and versions
- gradle-docker-jib - Build Docker images with Jib
- gradle-testing-setup - Configure Spring Boot testing
- Spring Boot Gradle Plugin Documentation
- Spring Boot Reference Guide
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon