I would like to display the time-stamp of when the application was built in an about box. This will allow me tracking different versions of the application. How can I retrieve this information in Java?
-
2which build tool you are using ? – jmj Oct 23 '10 at 10:04
-
Is there a way to do this in the NetBeans build environment? – jacknad Oct 23 '10 at 10:12
-
@JackN NB uses both ant and maven. it depends which build tool you are using. in simple NB project it uses ANT so follow the solution given for ant – jmj Oct 23 '10 at 10:13
-
@org.life.java I use eclipse with JDK 1.3 – Artium Oct 23 '10 at 10:34
-
@Artium There should be a build.xml file , check that. and refer the solution for ant. if its not there let us know – jmj Oct 23 '10 at 10:36
-
@org.life.java There is no build.xml. I have build.properties and Application.Descriptor. The latter is something J2Me specific I think. – Artium Oct 23 '10 at 10:52
-
@Artium what type of project is this ?, is it j2me? web app ? – jmj Oct 23 '10 at 10:53
-
@Artium for J2ME I would strongly recommended use `MIDlet-Version` to version your application and use 1.0,2.0 like version no this is standard practice for j2me application. – jmj Oct 23 '10 at 11:06
4 Answers
There's a much simpler maven solution which doesn't require the antrun plugin. Maven has a special variable maven.build.timestamp (since Maven 2.1.0-M1).
<plugin>
<artifactId>maven-war-plugin</artifactId> <!-- or maven-jar-plugin -->
<version>2.2</version>
<configuration>
<archive>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
This will produce a line "Build-Time: yyyyMMdd-HHmm". The format can be customized with:
<properties>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
</properties>
The pattern has to comply with the format of SimpleDateFormat.
Reference: Maven Documentation

- 9,147
- 4
- 29
- 37
You need to tell your build process to put the time stamp into a Java properties file, from which your application can then read it. Another good option to put it would be the jar manifest file.
For ant, you want to use the tstamp and property tasks, see this for an example.
While you are at it, you might also wish to include a source control revision number.

- 257,207
- 101
- 511
- 656
-
In addition to the property file, I prefer to put build number and compile time in a version class as part of the source and use that to report. Property files tend to be copied to new installs making it probable that an incorrect version is reported. (This way the application can log if the build number in the property file != the compiled-in build number.) – rsp Oct 23 '10 at 11:12
-
Explicitly put it a file. Just reading timestamps of files will break if the file is e.g. repacked later. – Thorbjørn Ravn Andersen Oct 23 '10 at 11:13
-
"Property files tend to be copied to new installs making it probable that an incorrect version is reported. " Those files should end up inside of the jar file. No one messes with them (and if they do, that's their problem). – Thilo Oct 23 '10 at 11:16
-
1In the example they stop short of showing how to read the Built-Date property... any idea how can I read this from my java code? – Charbel Sep 06 '11 at 11:13
for Maven:
In pom.xml file, add the following
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<filters>
<filter>${basedir}/target/filter.properties</filter>
</filters>
use Maven AntRun plugin to generate the build time,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<mkdir dir="${project.build.directory}"/>
<tstamp>
<format property="last.updated"
pattern="yyyy-MM-dd hh:mm:ss"/>
</tstamp>
<echo file="${basedir}/target/
filter.properties" message="build.time=${last.updated}"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
Then set the pom file to use the default manifest file
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
<!--
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true
</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true
</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Built-By>${user.name}</Built-By>
<Build-Jdk>${java.version}</Build-Jdk>
</manifestEntries>
</archive>
-->
</configuration>
</plugin>
Then generated MANIFEST.MF in the jar file will look like this.
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: admin
Build-Jdk: 1.5.0_14
Specification-Title: App Name
Specification-Version: 0.1 - 2008-02-21 01:03:13
Specification-Vendor: Company Name
Implementation-Title: App Name
Implementation-Version: 0.1 - 2008-02-21 01:03:13
Implementation-Vendor: Company Name
Build-Time: 2008-02-21 01:03:13
Resources
for ANT
<?xml version="1.0"?>
<project name="tstamp" basedir="." default="jar">
<property name="src" value="src"/>
<property name="obj" value="obj"/>
<property name="jar" value="tstamp"/>
<target name="clean">
<delete file="${jar}.jar"/>
<delete dir="${obj}"/>
<delete dir="${doc}"/>
</target>
<target name="compile">
<javac srcdir="${src}" destdir="${obj}" source="1.4" debug="true"
deprecation="true" />
</target>
<target name="jar" depends="compile">
<tstamp/>
<jar jarfile="${jar}-${DSTAMP}${TSTAMP}.jar" compress="true">
<fileset dir="${obj}" includes="**/*"/>
<fileset dir="${src}" includes="**/*"/>
</jar>
</target>
</project>
The above build.xml outputs a jarfile named 'tstamp-200307011540.jar'
Resource
-
1While this answer shows how most people would include the version number it lacks to show how to access the value from the application. Keep in mind every JAR, WAR or EAR can have a manifest so there are numerous of them on one classpath. – Queeg Nov 17 '20 at 07:21
I normally follow this alternative approach to the MANIFEST, as this is easily accessible from anywhere in our applications.
package com.livngroup.sandbox;
import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import org.apache.commons.io.FileUtils;
import org.joda.time.DateTime;
public enum Versioning {
INSTANCE;
public final DateTime buildTime;
private Versioning() {
this.buildTime = this.getLastModifiedDate();
}
private DateTime getLastModifiedDate() {
try {
return new DateTime(this.getLastModifiedFile().lastModified());
} catch (Exception e) {
try {
URLConnection conn = Versioning.class.getResource(Versioning.class.getSimpleName()+".class").openConnection();
return new DateTime(conn.getLastModified());
} catch (Exception e2) {
return new DateTime(0L); //Just a fallback
}
}
}
private File getLastModifiedFile() {
try {
URL url = Versioning.class.getResource(Versioning.class.getSimpleName()+".class");
File dir = new File(url.toURI()).getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
//System.out.println("classes.dir: "+dir);
String[] extensions = null;
File lastModifiedFile = null;
for (Iterator<File> iterator = FileUtils.iterateFiles(dir, extensions, true); iterator.hasNext();) {
File file = iterator.next();
if(lastModifiedFile==null || FileUtils.isFileNewer(file, lastModifiedFile)) {
lastModifiedFile = file;
}
}
//System.out.println("lastModified: "+lastModified);
return lastModifiedFile;
} catch (Exception e) {
return null;
}
}
}
Obviously the build time can then easily be accessed as
Versioning.INSTANCE.buildTime

- 171
- 1
- 7