31

I'm trying to display the application version of my Spring Boot application in a view. I'm sure I can access this version information, I just don't know how.

I tried following this information: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html, and put this in my application.properties:

info.build.version=${version}

And then loading it @Value("${version.test}") in my controller, but that doesn't work, I only get errors like:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'version' in string value "${version}"

Any suggestions on what the proper way to get information like my app version, the spring boot version, etc into my controller?

Erik Pragt
  • 13,513
  • 11
  • 58
  • 64

5 Answers5

48

You can also add this in build.gradle :

springBoot {    
    buildInfo() 
}

Then, you can use BuildProperties bean :

@Autowired
private BuildProperties buildProperties;

And get the version with buildProperties.getVersion()

Clément Poissonnier
  • 1,289
  • 2
  • 12
  • 26
  • If you're using Eclipse IDE you may have some dificulties with that plugin. I've made a post for this issue https://stackoverflow.com/questions/60140145/springboot-gradle-plugin-not-working-with-eclipse – aee Jun 18 '20 at 19:26
16

As described in the reference documentation, you need to instruct Gradle to process you application's resources so that it will replace the ${version} placeholder with the project's version:

processResources {
    expand(project.properties)
}

To be safe, you may want to narrow things down so that only application.properties is processed:

processResources {
    filesMatching('application.properties') {
        expand(project.properties)
    }
}

Now, assuming that your property is named info.build.version, it'll be available via @Value:

@Value("${info.build.version}")
Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Hi Andy, thanks for the reply. I have tried this, but whenever I run the Spring Boot application from my IDE, I get the error: Could not resolve placeholder 'version' in string value "${version}". I added this to my application.properties: `info.build.version=${version}`, and this to my controller: `@Value("${info.build.version}") private String applicationVersion;` – Erik Pragt Jan 23 '16 at 23:55
  • @ErikPragt Depending on what IDE you are using, and how you have imported your Gradle project, Gradle probably isn't being run so it hasn't had a chance to process your application.properties file. Does it work on the command line (`./gradlew bootRun`, for example)? – Andy Wilkinson Jan 24 '16 at 09:12
  • yes, that's of course a bit silly of me, I run it from my IDE, not from Gradle. Is there also a way to do it in a way that it always works? For example, the ResourceBanner.java of Spring Boot does a similar thing.... – Erik Pragt Jan 24 '16 at 11:42
  • @AndyWilkinson: can you help with this post. http://stackoverflow.com/questions/38752485/how-to-ignore-placeholder-value-if-not-supplied-in-properties-file-in-spring-boo – brain storm Aug 03 '16 at 22:35
  • This breaks integration tests. – Adam Arold Jan 07 '17 at 16:42
  • You can use Spring profiles to enable running it from the IDE see my answer here https://stackoverflow.com/questions/38752485/how-to-skip-placeholder-value-if-not-supplied-in-properties-file-in-spring-boot/44582048#44582048 – Tobias Tobiasen Jun 16 '17 at 06:21
3

I've resolved this by adding into application.yml the following:

${version?:unknown}

It also work from cli:gradle bootRun and also from IntelliJ and you don't have to call the Gradle task processResources before launching in IntelliJ or use spring profiles.

This work with Gradle ver:4.6 and also Spring Boot ver: 2.0.1.RELEASE. Hope it helps ;)

brebDev
  • 774
  • 10
  • 27
2

I have solved it this way: Define your info.build.version in application.properties:

info.build.version=whatever

use it in your component with

@Value("${info.build.version}")
private String version;

now add your version info to your build.gradle file like this:

version = '0.0.2-SNAPSHOT'

then add a method to replace your application.properties with a regex to update your version information there:

def updateApplicationProperties() {
    def configFile = new File('src/main/resources/application.properties')
    println "updating version to '${version}' in ${configFile}"
    String configContent = configFile.getText('UTF-8')
    configContent = configContent.replaceAll(/info\.build\.version=.*/, "info.build.version=${version}")
    configFile.write(configContent, 'UTF-8')
}

finally, ensure the method is called when you trigger build or bootRun:

allprojects {
    updateVersion()
}

that's it. This solution works if you let Gradle compile your app as well as if you run your Spring Boot app from the IDE. The value will not get updated but won't throw an exception and as soon as you run Gradle it will be updated again.

I hope this helps others as well as it solved the problem for me. I couldn't find a more proper solution so I scripted it by myself.

user3105453
  • 1,881
  • 5
  • 32
  • 55
0

For Kotlin user, what works for me was :

  1. application.properties

In the application.properties you add a placeholder that will be replace with your value by gradle.

    project.version= ${version}
  1. build.gradle.kts

Add a task so gradle will replace the value

    tasks.processResources { filesMatching("**/application.properties") { expand(project.properties) } }
  1. Service.kt

Inject the value in your services

    @Value("\${project.version}") lateinit var version: String
Nicolas
  • 663
  • 6
  • 17