There are a few ways to get your application version with Spring Boot. One approach is using Maven resource filtering to add the version number as an enviroment variable in the application.yml during the build. Another approach is to use the Implementation-Version stored in the manifest file.

Maven resource filtering

First of all, you need to enable resource filtering for your application.yml

<build>
  <resources>
    <resource>
      <directory>${basedir}/src/main/resources</directory>
      <filtering>true</filtering>
      <includes>
        <include>**/application*.yml</include>
      </includes>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

Then you need to add a maven parameter to the application.yml. @ is used here instead of the standard ${} notation to prevent conflicts

app:
  version: '@project.version@'

And we can then retrieve it using @Value

@Value("${info.app.version:unknown}") String version

The upside of this approach is that you always have a version number even when you start your application from your IDE, also by putting your variable in info.app.version, if you use Spring boot actuator, your version will be automatically available under the /info endpoint. However, this approach does require quite a bit of configuration.

Using the manifest file

Alternatively, maven stores the Implementation-Version in the MANIFEST.MF file when building a jar. If you dont mind not having a version until you run it from a jar, you can use this to get the application version. Java allowes for easy access to this using:

getClass().getPackage().getImplementationVersion()

This will retrieve the version number of the class you supplied, so if you put this in a common-library, you will always get the library version. We can solve this with the following code:

public class VersionHolder {

    private final String version;

    public VersionHolder(ApplicationContext context) {
        version = context.getBeansWithAnnotation(SpringBootApplication.class).entrySet().stream()
                .findFirst()
                .flatMap(es -> {
                    final String implementationVersion = es.getValue().getClass().getPackage().getImplementationVersion();
                    return Optional.ofNullable(implementationVersion);
                }).orElse("unknown");
    }

    public String getVersion() {
        return version;
    }
}

@Configuration
public class MyConfig{

    @Bean
    VersionHolder getVersionHolder(ApplicationContext context){
        return new VersionHolder(context);
    }
}

This will try to find a bean with the @SpringBootApplication annotation, and use that class to determine your application version. Now you have a generic way to get your application version :)

shadow-left