Gradle
Spring Boot
Build Automation
Project Configuration
Dependency Management

Getting the Gradle.build version into Spring Boot

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Spring Boot can expose the project version defined in build.gradle through the /actuator/info endpoint or by injecting it into application properties. The standard approach is to use the spring-boot-gradle-plugin's build info task, which generates a build-info.properties file at build time. This file is automatically picked up by Spring Boot's BuildProperties bean, making the version available for injection throughout the application.

Configure build.gradle

groovy
1plugins {
2    id 'org.springframework.boot' version '3.2.0'
3    id 'io.spring.dependency-management' version '1.1.4'
4    id 'java'
5}
6
7group = 'com.example'
8version = '1.2.3'
9
10springBoot {
11    buildInfo()  // Generates META-INF/build-info.properties
12}

This generates build/resources/main/META-INF/build-info.properties containing:

properties
1build.artifact=my-app
2build.group=com.example
3build.name=my-app
4build.time=2025-03-02T14:00:00Z
5build.version=1.2.3

Inject BuildProperties

java
1import org.springframework.boot.info.BuildProperties;
2import org.springframework.web.bind.annotation.GetMapping;
3import org.springframework.web.bind.annotation.RestController;
4
5@RestController
6public class VersionController {
7
8    private final BuildProperties buildProperties;
9
10    public VersionController(BuildProperties buildProperties) {
11        this.buildProperties = buildProperties;
12    }
13
14    @GetMapping("/version")
15    public String getVersion() {
16        return buildProperties.getVersion();  // "1.2.3"
17    }
18
19    @GetMapping("/build-info")
20    public Map<String, String> getBuildInfo() {
21        return Map.of(
22            "version", buildProperties.getVersion(),
23            "artifact", buildProperties.getArtifact(),
24            "group", buildProperties.getGroup(),
25            "time", buildProperties.getTime().toString()
26        );
27    }
28}

Method 2: Expose via Actuator Info Endpoint

Spring Boot Actuator automatically picks up build-info.properties:

groovy
1// build.gradle
2dependencies {
3    implementation 'org.springframework.boot:spring-boot-starter-actuator'
4}
5
6springBoot {
7    buildInfo()
8}
yaml
1# application.yml
2management:
3  endpoints:
4    web:
5      exposure:
6        include: info, health
7  info:
8    build:
9      enabled: true

Access GET /actuator/info:

json
1{
2  "build": {
3    "artifact": "my-app",
4    "group": "com.example",
5    "name": "my-app",
6    "time": "2025-03-02T14:00:00Z",
7    "version": "1.2.3"
8  }
9}

Method 3: Property Expansion in application.properties

Gradle can expand properties directly in Spring Boot's configuration files:

groovy
1// build.gradle
2processResources {
3    expand(project.properties)
4}
properties
# application.properties
app.version=${version}
app.name=${name}
java
@Value("${app.version}")
private String appVersion;  // "1.2.3"

Kotlin DSL (build.gradle.kts)

kotlin
1plugins {
2    id("org.springframework.boot") version "3.2.0"
3    id("io.spring.dependency-management") version "1.1.4"
4    kotlin("jvm") version "1.9.22"
5}
6
7group = "com.example"
8version = "1.2.3"
9
10springBoot {
11    buildInfo()
12}
13
14// Property expansion for Kotlin DSL
15tasks.processResources {
16    expand(project.properties)
17}

Method 4: Custom Build Info Properties

Add custom properties to the build info:

groovy
1springBoot {
2    buildInfo {
3        properties {
4            additional = [
5                'description': 'My Spring Boot Application',
6                'environment': System.getenv('DEPLOY_ENV') ?: 'development',
7                'javaVersion': JavaVersion.current().toString()
8            ]
9        }
10    }
11}
java
// Access custom properties
String environment = buildProperties.get("environment");  // "production"
String javaVersion = buildProperties.get("javaVersion");  // "17"

Method 5: Manifest File

Write the version to MANIFEST.MF and read it at runtime:

groovy
1// build.gradle
2jar {
3    manifest {
4        attributes(
5            'Implementation-Title': project.name,
6            'Implementation-Version': project.version
7        )
8    }
9}
java
1@Component
2public class AppVersion {
3
4    public String getVersion() {
5        return getClass().getPackage().getImplementationVersion();
6        // Returns "1.2.3" from MANIFEST.MF
7    }
8}

This works but is less reliable than BuildProperties because the manifest is only available when running from a packaged JAR, not during development with gradle bootRun.

Dynamic Version from Git

groovy
1// build.gradle
2plugins {
3    id 'com.palantir.git-version' version '3.0.0'
4}
5
6version = gitVersion()  // e.g., "1.2.3-5-gabcdef" or "1.2.3" on a tag
7
8springBoot {
9    buildInfo()
10}

This sets the version automatically based on Git tags, including commit count and hash for non-tagged commits.

Common Pitfalls

  • BuildProperties bean not found: If you get No qualifying bean of type 'BuildProperties', you forgot springBoot { buildInfo() } in build.gradle. Without this, no build-info.properties is generated and Spring cannot create the bean.
  • Property expansion breaking YAML: expand(project.properties) in processResources replaces ${...} tokens in all resource files, including application.yml. This conflicts with Spring's ${} placeholder syntax. Use @...@ delimiters instead: set app.version=@version@ and configure expand to use @ delimiters.
  • Stale build info after version change: The build-info.properties file is generated at build time. If you change the version in build.gradle but do not rebuild (gradle clean build), the old version persists in the output. Always clean build for version changes.
  • BuildProperties unavailable during tests: Unit tests that do not run the full Spring Boot context may not have BuildProperties available. Use @ConditionalOnBean(BuildProperties.class) or provide a default value with @Value("${build.version:unknown}").
  • Manifest version null in development: getClass().getPackage().getImplementationVersion() returns null when running with gradle bootRun or from an IDE because the class is not loaded from a JAR. Use BuildProperties instead for reliable access during development.

Summary

  • Use springBoot { buildInfo() } in build.gradle to generate build-info.properties at build time
  • Inject BuildProperties to access version, artifact, group, and build time anywhere in the application
  • Enable Spring Boot Actuator to expose build info via GET /actuator/info automatically
  • Add custom properties to build info with the additional map in buildInfo { properties { ... } }
  • Use Git-based versioning plugins for automatic version derivation from tags
  • Prefer BuildProperties over manifest-based approaches for reliability during development

Course illustration
Course illustration

All Rights Reserved.