开发者

Displaying the build time-stamp in an application

I would like to display the time-stamp of when the appl开发者_如何学Cication was built in an about box. This will allow me tracking different versions of the application. How can I retrieve this information in Java?


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


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.


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

  • This blog

  • Maven cook book


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

  • tstamp documentation

  • this blog


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜