3

I want to access a value from the gradle.properties file in the root of my Spring Boot application. (To display the version of the project on the home page.)

I am building a war, deploying my Spring Boot application to a server, and using an external application.properties file (#9 on this list) so this solution won't work for me.

I tried this solution, but anywhere I put the gradle.properties file in the war (I've tried every possible location in that directory structure), I cannot access it using this method.

How can I do this?

Community
  • 1
  • 1
mattrowsboats
  • 582
  • 1
  • 6
  • 14

2 Answers2

3

This is what ended up working for me within the constraints specified above:

One-sentence summary

In order to work both in my deployment pipeline (gradle build -> war -> embedded tomcat) and in development (IntelliJ), I needed a dummy properties file for development and to copy over the actual properties file during the gradle build.

Code

./gradle.properties

version=x.x.x

./src/main/resources/my-project.properties

version=development

./build.gradle

war {
    rootSpec.exclude("**/my-project.properties")
    from('.') {
        include 'gradle.properties'
        into('WEB-INF/classes')
        rename('gradle.properties', 'my-project.properties')
    }   
}

./src/main/java/com/company/version/VersionComponent.java

private String getVersion() {
    String propertyVersion = "";
    Properties properties = new Properties();
    InputStream input = null;
    try {
        input = VersionComponent.class.getClassLoader().getResourceAsStream("my-project.properties");
        properties.load(input);
        propertyVersion = properties.getProperty("version");
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return propertyVersion;
}
mattrowsboats
  • 582
  • 1
  • 6
  • 14
1

I am working in grails, which is also built on spring boot. Alike you, I wanted to pass properties from my gradle file, but for me, it was from build.gradle and to be used during junit execution.

Note: for a list of ways to load application.properties, not gradle.properties, you can have a look here. Just to make sure we are on the same page, if you are trying to version the application you are using (possibly display it to some user), you should be setting it in application.properties not gradle.properties. If you want the latter, you need to replace the properties in the file you plan on using with gradle, and change out the value, which is more complex.

Regardless, here is one approach I have taken that lets me inject properties during my test execution, from build.gradle.

test {
    def defaultLoginUrl = System.getProperty("testing.defaults.loginUrl")

    systemProperty "testing.defaults.loginUrl", defaultLoginUrl?: "https://localhost:8443/"
}

And in my Java code:

public String getLoginUrl() {
    return System.getProperty("testing.defaults.loginUrl")
}

Lastly, if you want to access the file as an input stream, you should place it in the resources directory, and use the context to fetch it. However, application.properties is, in my opinion from reading your post, exactly what you want. This concept is similarly addressed in the question you quoted, as loading properties from a build file is not common practice when you are ready to deploy it.

Community
  • 1
  • 1
angryip
  • 2,140
  • 5
  • 33
  • 67
  • I already know how to load values from application.properties so that's not my problem. I also am not able to alter where the version value is being placed (your suggestion of placing it in the application.properties makes sense, but that's not where it is). Your solution seems like a good one for testing and executing those tests via gradle, but that also isn't my situation. We are executing the Spring Boot app as a war using the embedded tomcat instance, so setting some System properties in the gradle task and then calling them isn't a solution for me. Thanks for your thoughts! – mattrowsboats Jul 14 '16 at 17:48
  • 1
    @MattRowe The only way you can then make this work is as noted by my last paragraph, placing the file in the resource directory and parsing it. In grails, the path needed is src/main/webapp , though in spring, it might be src/main/resources. Then when you want to load the file, you can refernece to it like: /gradle.properties . You can also load it with something like this: https://kamwo.me/java-load-file-from-classpath-in-spring-boot/ , or this: http://stackoverflow.com/questions/3294196/load-resource-from-anywhere-in-classpath – angryip Jul 14 '16 at 18:17