Inject Build Time (timestamp) Property Using Maven
28th May 2007 - By Aaron
In your pom.xml you have the ability to turn on resource filtering that replaces variables in resource files with actual values. These are useful for things like ${pom.name} and ${pom.version}. Your pom.xml section would look something like this…
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
And your properties file could contain something like these
# Build Time Information
APPLICATION.NAME=${pom.name}
APPLICATION.VERSION=${pom.version}
There is a list of available properties that you can use here http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide
Onto the difficult part. There is no automatic variable that references a current timestamp for use as a buildtime property. I want a buildtime property available to my webapp so I can see very easily when the currently deployed version was built.
Here is how I accomplished it (it wasn’t that hard).
There are a few steps to this.
- Put a placeholder in the properties file.
- Replace the placeholder with a timestamp at build time
- Remove the updated file to allow the file to be refreshed at the next build time
Step 1: Add a property such as APPLICATION.BUILDTIME=HOLDER
Step 2: Include an ant execution in your build. This is not extremely difficult. Place a plugin in the plugins tag in the POM.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>set-build-time</id>
<phase>process-sources</phase>
<configuration>
<tasks>
<tstamp>
<format property="timestamp" pattern="yyyy/MM/dd HH:mm:ss z"/>
</tstamp>
<replaceregexp byline="true">
<regexp pattern="APPLICATION\.BUILDTIME=HOLDER" />
<substitution expression="APPLICATION.BUILDTIME=${timestamp}" />
<fileset dir="src/main/resources/pathToPropertyFileDirectory" includes="*.properties" />
</replaceregexp>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This will do a regular expression find and replace on HOLDER with the timestamp.
Step 3: I am using continuum so I must clean up my files before continuing. I use a post cleanup method, and it looks something like this. I put this under the profiles tag.
<profile>
<id>cleanProperties</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>cleanProperties</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete dir="./src/main/resources/pathToPropertyFileDirectory" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>As a final note, do not forget to include the profile when you build your project. The flag is -P.
And there you have it. Since it is a POST cleanup you may have to build twice for it to operator properly.
June 15th, 2007 at 5:30 am
I try this again - the HTML formatter didn’t like my input… Thanks for this great hint. Two comments:
First, you need an extra dependency in that allows executing optional ant tasks:
<plugin>
…
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.6.5</version>
</dependency>
</dependencies>
</plugin>
Second, you can also patch just the generated resource in the project’s build directory, thus eleminating the need for the cleanup task. Maven guarantees that all POM-defined plugins are executed after default tasks in the respective lifecycle phases, we can safely assume that the resource file has already been processed and copied to the build directory.
Martin
October 3rd, 2007 at 3:30 am
i found a simpler solution using ant’s tstamp task: