drhender
drhender

Reputation: 480

Referencing gradle properties in application.yml

If this question has been asked and answered, or that there is doc or an example, please forgive me. I have spent several hours looking for a solution here on stackoverflow and even more time in the gradle doc and haven't been able to make this work.

I have a spring boot project with a pretty standard maven layout. I am using gradle 2.4. here's the layout of the relevent files:

/gradle.properties
/build.gradle
/settings.gradle
/src/main/resources/application.yml

In gradle.properties, I have defined the following properties:

name=Sample microservice
description=brief description of the service goes here
version=1.0.0-SNAPSHOT

In my application.yml file, I'd like to set corresponding spring properties to those same values. (I'd like to define them together in one place and use them in several places. Since version is typically defined in gradle.properties, I want to cluster the rest there as well.)

I've tried the following line in application.yml, but things aren't working as hoped:

info.app.name: ${name}
info.app.description: ${description}
info.app.version: ${version}

(I also tried ${project.name}, etc. That didn't work either.)

I ran gradlew properties... the properties are listed with values as expected. However, when I run a build, the yaml file is copied into \build\resources\main as expected, but the ${value} tokens are not resolved.

I also included the following lines in build.gradle file, but things remain unresolved.

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

(My goal is to use the actuator /info endpoint to provide the values of those properties to a service caller.)

Any suggestions or pointers to documentation that help would be greatly appreciated!

Upvotes: 14

Views: 28780

Answers (3)

m0j0hn
m0j0hn

Reputation: 572

I recently faced same situation - here is what worked for me.

TL;DR: In Spring Boot 1.2.5, info.* properties in application.yml are ignored by /info; need to use application.properties for info.* properties.

First, create src/main/resources/application.properties with this content:

info.build.description=${description}
info.build.name=${name}
info.build.version=${version}

Second, add this snippet to your build.gradle file:

processResources {
    filesMatching("**/application.properties") {
        expand( project.properties )
    }
}

Next, run your build as normal. This will process the application.properties file and replace the variables with their build-time values as it copies the file to build/resources/main/application.properties .

For me, when running the deployed .jar, my /info endpoint is populated with the expanded values, which is the goal.

Note that for bonus points you can add this to your build.gradle to get Git info in the /info endpoint, too:

apply plugin: "com.gorylenko.gradle-git-properties"

You will also need to add this to the dependencies section of build.gradle, for that to work:

classpath 'gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:1.+'

Hope this helps!

Upvotes: 11

drhender
drhender

Reputation: 480

After more tinkering, I discovered that the values are expanded at runtime. When Spring defines the properties in the environment the ${value} tokens are expanded the way I had hoped. After more thought, this makes perfect sense. Those values can't be resolved at build-time because that can be set in a variety of places. The runtime spring properties reflect the current value, whether the property is set via application.yml in the jar, application.yml sitting along side the jar, or via a -d switch when the jar is executed.

Upvotes: 0

TobiSH
TobiSH

Reputation: 2919

Have you thought about using the Copy task? There you can define variables to expand:

application.yml:

info.app.name: ${project.name}
info.app.description: ${project.description}
info.app.version: ${project.version}
info.app.foo: ${foo}

build.gradle:

task copyConfig(type: Copy) {
  from ('src/main/resources') 
  into 'build/config'

  // refer to project and replace foo by string bar
  expand(project: project, foo: 'bar')

}

If you want to keep your properties seperated you can also refer to a properties file:

expand(project.properties)

You might want to take a look at the gradle doc: https://docs.gradle.org/current/userguide/working_with_files.html

Did you get the idea?

Upvotes: 2

Related Questions