126

I am using maven 3.0.4 and would like to make the build timestamp accessible to my application. For this, I'm putting a placeholder in a .properties file and let maven filter on build. While this is working fine for ${project.version}, ${maven.build.timestamp} is not substituted on filtering.

The property seems to be available on build - I can use it to modify the artifact name:

<finalName>${project.artifactId}-${maven.build.timestamp}</finalName>

So why is it not available for resource filtering? And, more importantly, how do I make it accessible?

Cœur
  • 37,241
  • 25
  • 195
  • 267
kostja
  • 60,521
  • 48
  • 179
  • 224

4 Answers4

254

I have discovered this article, explaining that due to a bug in maven, the build timestamp does not get propagated to the filtering. The workaround is to wrap the timestamp in another property:

<properties>
   <timestamp>${maven.build.timestamp}</timestamp>
   <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
</properties>

Filtering then works as expected for

buildTimestamp=${timestamp}
Java Crazy
  • 57
  • 7
kostja
  • 60,521
  • 48
  • 179
  • 224
  • 1
    Just a note for others, I had problem with that, because I'm using Tomcat within Eclipse and it seems, that it's not working fine - replacement is ok in `target/${project}` folder, but in my actuall configuration Tomcat is not using this folder... – Betlista Mar 01 '13 at 08:49
  • 3
    @Betlista yeah, server integration in eclipse seems to use the source directory. It was one of the reasons why I abandoned eclipse integration and use maven from command line. – kostja Mar 01 '13 at 13:32
  • 1
    Given there are multiple places in a pom where I need a timestamp, but in different formats (for example a file name and a build time string), how can I use `maven.build.timestamp.format` multiple times? – Daniel Alder Apr 29 '14 at 11:25
  • AFAIK this is not possible, since the format element is not subject to the individual properties. As workaround, you will probably have to put the string somewhere in a verbose format, so you can modify it later on programmatically. – kostja Apr 29 '14 at 11:59
  • 13
    No worky. Filtering replaces `${timestamp}` with the literal string `${maven.build.timestamp}`. – Kevin Krumwiede Aug 14 '14 at 23:29
  • It works, even in 3.3.9. Only trouble I had was that my property was also named ${timestamp} and was overwritten by the buildnumber-helper. So don't mix with that plugin. – Ivo Limmen Oct 20 '16 at 09:14
  • Works perfectly, when used in conjunction with spring boot intializr – VeRo Oct 10 '17 at 22:14
  • Works! But i get weird unix timestamp instead of formatted date. (example 1526536472093) – TomazStoiljkovic May 17 '18 at 06:03
  • @TomazStoiljkovic do you define the format property for the timestamp? See the 'Available Variables' section in https://maven.apache.org/guides/introduction/introduction-to-the-pom.html – kostja May 17 '18 at 12:39
  • 2
    If you are using SpringBoot, you have to write `buildTimestamp=@timestamp@` – Julien Feniou Nov 14 '18 at 15:30
  • The bug has been "bandaided" so the properties declaration is no longer required, the other answers here... – rogerdpack Apr 15 '19 at 16:32
  • 1
    If you use filtering within the maven-assembly-plugin v3.3.0, the ${maven.build.timestamp} is still not directly available, and you need to use the workaround noted here. See also https://issues.apache.org/jira/browse/MASSEMBLY-603 – Cheeso Jul 01 '20 at 15:32
  • 1
    @JulienFeniou Thanks! `build.date=@timestamp@` worked for me and saved my afternoon! Cheers. – AvaTaylor Nov 18 '20 at 19:58
  • maven.build.timestamp.format not working for me in production server. It runs in locally with intellij build. How can I update format? – Halil İbrahim Oymacı Nov 27 '20 at 08:08
  • Can use `${buildDate}`, without declaring extra properties (aside date format) ;-) – Felix Aballi Jul 05 '21 at 19:37
21

I can confirm as of Maven 3.x {maven.build.timestamp} is "working" now. They work arounded the problem, apparently. No additional properties workaround needed anymore.

However, be careful your "filtering" plugin (maven-resources-plugin) is up to date. It needs to be relatively new, so if mvn help:effective-pom shows an old version (ex: 2.6), bump it to something newer, fixed it for me, 3.x ex:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.1.0</version>
</plugin>

<properties><timestamp>... workaround is no longer required...

This also cleared up, kind of, why it was working in IntelliJ but not the command line. IntelliJ probably uses their own "modified/internal" maven constants, so it was working there, but not from maven command line.

Also note if you add a filtering resource directory to you pom, you may need to also "re-add" the default directory, it gets lost, ex:

  <resource>
    <directory>src/main/resources-filtered</directory> <!-- to get "maven.build.timestamp" into resource properties file -->
    <filtering>true</filtering>
  </resource>
  <resource>
    <directory>src/main/resources</directory> <!-- apparently have to add this is you have the other... -->
  </resource>

NB if you're using spring boot as your parent, you have to use @maven.build.timestamp@ instead. Also note if you're using spring boot there's a file META-INF/build-info.properties that is optionally created by the spring-boot-maven-plugin that you can read (spring provides a BuildProperties bean for convenience reading it).

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • 4
    Unfortunately this does not work yet for _maven-war-plugin_ (``) :-( see [MWAR-415](https://issues.apache.org/jira/browse/MWAR-415) -> so still have to use the workaround there – msa Feb 11 '20 at 21:39
  • 2
    Different plugins do filtering differently. If you use filtering within the maven-assembly-plugin v3.3.0, the ${maven.build.timestamp} is still not directly available, and you need to use the `...` workaround. See also https://issues.apache.org/jira/browse/MASSEMBLY-603 – Cheeso Jul 01 '20 at 15:33
  • build-info goal solution works as an alternative, but note that you have to put build-info goal before e.g. the repackage goal, if you already have repackage defined. as a sidenote, I couldn't make maven.build.timestamp.format work, so I ended up formatting the timestamp on the frontend - no big deal – hello_earth May 30 '21 at 08:46
4

In order to enrich the Stackoverflow content for others, that like me, found this post as a way to solve the "problem" of ${maven.build.timestamp}. This is not a maven bug, but an expected behavior of m2e, as can be seen in this post.

Therefore, I believe that we can not expect the solution to be "corrected", since, from what I understand, the correction involves conceptual issues.

In my case, what I did was use the plugin (buildnumber-maven-plugin) as described in this other post.

Community
  • 1
  • 1
Bob Rivers
  • 5,261
  • 6
  • 47
  • 59
  • I found `buildnumber-maven-plugin` to have similar problems, namely that the variable it generates is only available in certain contexts, NOT filtering. You may or may not be able to overcome that by tinkering with the execution phase or goals, but the built-in solution seems so much simpler. – MarkHu Aug 04 '17 at 02:05
4

Adding Maven properties at the pom project level doesn't take into account correct local Timezone, so timestamp may appear wrong :

<properties><timestamp>${maven.build.timestamp}</timestamp></properties>

Using the build-helper-maven-plugin applies the correct timezone and current daylight saving to the timestamp :

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>1.9.1</version>
            <executions>
                <execution>
                    <id>timestamp-property</id>
                    <goals>
                        <goal>timestamp-property</goal>
                    </goals>
                    <configuration>
                        <name>timestamp</name>
                        <pattern>yyyy-MM-dd HH:mm:ss</pattern>
                        <timeZone>Europe/Zurich</timeZone>
                    </configuration>
                </execution>
            </executions>
        </plugin>
     </plugins>
     <resources>
         <resource>
             <directory>src/main/resources</directory>
             <filtering>true</filtering>
         </resource>
     </resources>
 </build>

When packaging, Maven will replace any token timestamp in /resources folder, e.g. resources/version.properties :

build.timestamp=${timestamp}

You can then load this properties file in your Application.

icyerasor
  • 4,973
  • 1
  • 43
  • 52
skay
  • 1,681
  • 1
  • 14
  • 13