Cannot get maven project.version property in a Spring application with @Value
To get access to Maven properties in Spring Boot application all we need is map them with delimiter @
in the application.properties
like this:
[email protected]@
[email protected]@
Then use them in the app like ordinary properties, for example:
@Service
public class SomeService {
@Value("${app.version}")
private String appVersion;
// other stuff
}
Source: Automatic Property Expansion Using Maven
But if you are using yaml to store application properties, you may need to replace delimiter @
with some other one, for example ^
in our pom.xml
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>^</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
Or even simpler - just replace variable resource.delimiter
in propeties
block of your pom.xml:
<properties>
<java.version>11</java.version>
<resource.delimiter>^</resource.delimiter>
</properties>
Then use it in your property file, for example:
app:
version: ^project.version^
name: ^project.name^
After some research and trials on how to get the Maven project version in a SpringBoot application I couldn't find anything working for me.
Using a manifest is definitively a rotten path due to class loaders issues, i.e. one gets the first manifest Spring finds, which in my case was not the one of my application.
One solution I have found is to use the maven resources plugin to "filter" (replace) properties in resource files. In this case the Spring application.properties
.
Below are the steps to make this work.
In the pom file, activate resources filtering with the following definition:
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
</includes>
</resource>
</resources>
In the application.properties
file:
[email protected]@
[email protected]@
build.timestamp=@timestamp@
Notice the @property@ instead of ${property}. in the application.properties
file.
The spring-boot-starter-parent
pom redefines the standard ${}
delimiter as @
:
<resource.delimiter>@</resource.delimiter>
<!-- delimiter that doesn't clash with Spring ${} placeholders -->
<delimiters>
<delimiter>${resource.delimiter}</delimiter>
</delimiters>
One can then access those properties in Spring using @Value
like this:
@Value("${application.name}")
private String applicationName;
@Value("${build.version}")
private String buildVersion;
@Value("${build.timestamp}")
private String buildTimestamp;
A sample project is available here.