Asdfasf

Friday, October 12, 2012

Placing Build Details into MANIFEST.MF via ANT / Maven

If it is needed to place build details into MANIFEST.MF file under META-INF directory of jar file, that can be accomplished via ANT in build.xml as below

      <tstamp>  
           <format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />  
      </tstamp>  
      <target name="build" depends="compile">  
           <war warfile="${dist.home}\${dist.war}" basedir="${deploy.home}" webxml="${deploy.home}\WEB-INF\web.xml" excludes="javadoc">  
             <manifest>               
              <attribute name="Built-By" value="${user.name}"/>            
                 <attribute name="Built-Date" value="${TODAY}" />       
              <attribute name="Implementation-Vendor" value="XXXX"/>  
              <attribute name="Implementation-Title" value="${app.name}"/>  
              <attribute name="Implementation-Version" value="${release.number}"/>               
             </manifest>  
           </war>  
      </target>  

Just put required attributes between manifest tag of war or jar task. Output of MANIFEST.MF file would be as below:

 Manifest-Version: 1.0  
 Ant-Version: Apache Ant 1.7.1  
 Created-By: 14.2-b01 (Sun Microsystems Inc.)  
 Built-By: fkul  
 Built-Date: 2012-10-12 17:18:20  
 Implementation-Vendor: XXXX  
 Implementation-Title: product  
 Implementation-Version: 01_01_00_Build01  



Additionally, how those attributes in MANIFEST.MF can be read? As below:

   public static String getBuildDetails() throws MalformedURLException, IOException {  
     Class clazz = ThisClass.class;  
     String className = clazz.getSimpleName() + ".class";  
     String classPath = clazz.getResource(className).toString();  
     if (!classPath.startsWith("jar")) {  
       // Class not from JAR  
       return null;  
     }  
     System.out.println("ClassPath=" + classPath);  
     String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) + "/META-INF/MANIFEST.MF";  
     System.out.println("ManifestPath=" + manifestPath);  
     Manifest manifest = new Manifest(new URL(manifestPath).openStream());  
     Attributes attr = manifest.getMainAttributes();  
     return attr.getValue("Implementation-Title") + " : " + attr.getValue("Implementation-Version");  
   }  

By shipping build details in MANIFEST.MF and reading them on runtime is a good idea to inform user of product on runtime as which version of product is currently running.

In Maven

If you are using maven, that can be accomplished in pom as below:

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

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <version>2.3</version>
 <configuration>
   <archive>
  <manifest>
    <addClasspath>true</addClasspath>
  </manifest>
  <manifestEntries>            
   <Built-Date>${maven.build.timestamp}</Built-Date>            
   <Implementation-Vendor>${vendor}</Implementation-Vendor>
   <Implementation-Title>${name}</Implementation-Title>
   <Implementation-Version>${version}</Implementation-Version>
  </manifestEntries>
   </archive>
 </configuration>
</plugin>

No comments: