Spring Boot - Access build properties at runtime

Published by Alexander Braun on 19 May 2018 - tagged with Spring, Spring Boot, Java

This post describes how to access Maven build properties at run time. As an example I will use a simple command line tool built with Spring Boot.

Motivation

In the last few years I have build various command line tools for different teams and projects. In this context I noticed that it is often useful to log he version and build time of the tool to be able to provide adequate support. For example one team might face an issue with version 1.0.1 of the tool that has already been fixed in version 1.0.3. Being able to identify the tool version and build date based on the provided log file makes support inquiries much easier.

What are we going to build?

To demonstrate how accessing build properties at run time, we will build a simple command line tool, that just prints out the current date and time.

You can find the complete code for this project at github.

Spring Boot Application

Lets first create the main class for our command line tool. The code for BuildPropertiesDemo class is shown below:

package com.progressive.code.bp;

import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.info.BuildProperties;

@SpringBootApplication
public class BuildPropertiesDemoApplication implements CommandLineRunner {

    @Autowired
    private BuildProperties buildProperties;

    public static void main(String[] args) {
        SpringApplication.run(BuildPropertiesDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(String.format("Version: %s Time: %s", buildProperties.getVersion(), buildProperties.getTime()));
        System.out.println("Current Time is: " + LocalDateTime.now());
    }

}

There is not a lot going on here:

  • We added @SpringBootApplication annotation
  • The class implements CommandLineRunner - this allows Spring Boot to treat the application as command line tool and to simple execute the run method after startup.
  • In the run method we print out version and build time and of course we print out the current time

The interesting part is the BuildProperties object that gets injected via @Autowired annotation. This bean will ultimately provide the build information we use in the run method.

application.properties file

We can also adjust the application.properties file as shown below:

spring.application.name=BuildPropertiesDemo
spring.main.banner-mode=off

logging.level.root=off

Adding these properties will remove the Spring Boot banner that is typically being printed out at startup. In this case we also don't need the standard log entries Spring Boot creates. In case we face any issues, we can always change logging.level.root to INFO or even DEBUG to get more info about potential issues.

pom.xml file

There is one last step to implement: We have to change the pom.xml file as shown below:

<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <parent>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-parent</artifactid>
    <version>3.2.3</version>
    <relativepath></relativepath>
  </parent>
  <groupid>com.progressive.code.bp</groupid>
  <artifactid>BuildPropertiesDemo</artifactid>
  <version>1.0.0</version>
  <name>BuildPropertiesDemo</name>
  <description>Showing the usage of build properties in Spring Boot</description>
  <properties>
    <java.version>17</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter</artifactid>
    </dependency>

    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-test</artifactid>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-maven-plugin</artifactid>
        <configuration>
          <executable>true</executable>
        </configuration>
        <executions>
          <execution>
            <id>build-info</id>
            <goals>
              <goal>build-info</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

The key part in the pom.xml file is in the execution section. We have to add goal build-info. What this configuration does is: When the code is being compiled, the following build-info.properties file is being created and added to the jar file. In case you are interested, you can find the build-info.properties file in the target/classes/META-INF folder. Additional info can be found here.

build.artifact=BuildPropertiesDemo
build.group=com.progressive.code.bp
build.name=BuildPropertiesDemo
build.time=2018-05-18T22\:31\:28.497Z
build.version=1.0.0

Lets test the application

After building the application with mvn clean install, we can test if everything works by running it with ./BuildPropertiesDemo-1.0.0.jar in the target folder. In the pom.xml file we specified to create an executable jar file. If the command doesn't work on your local environment you can try running it with java -jar BuildPropertiesDemo-1.0.0.jar.

The example output should look like this:

Version: 1.0.0 Time: 2018-05-18T22:31:28.497Z
Current Time is: 2024-05-18T15:31:29.262188501

And that's it, we can now access version and build time from within our own Java classes.