apache_maven

In this small post i will present you how to

  1. Track and identify across your Apache Maven multi project builds all components, their versions, and class path if needed
  2. Get valuable information from your testing team, and add it to the GUI of your web applications

To solve the problem number 1, we will use Manifest files

On the Java platform, a manifest file is a specific file contained within a JAR archive. It is used to define extension and package related data. It is a metadata file that contains name-value pairs organized in different sections. If a JAR file is intended to be used as an executable file, the manifest file specifies the main class of the application. The manifest file is named MANIFEST.MF. [Wikipedia]

If you do nothing special in Maven., you will see across your jar files the following in all META-INF/MANIFEST.MF

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven

 

The solution I propose here will write all these META-INF/MANIFEST.MF the following  content:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: agent1
Build-Jdk: 1.6.0_20
Specification-Title: Unnamed - com.waltercedric:web:war:1.0.0-SNAPSHOT
Specification-Version: 1.0.0-SNAPSHOT
Specification-Vendor: waltercedric
Implementation-Title: Unnamed - com.waltercedric:web:war:1.0.0-SNAPSHOT
Implementation-Version: 1.0.0-SNAPSHOT
Implementation-Vendor-Id: com.waltercedric
Implementation-Vendor: waltercedric
buildDate: 2010.09.22-14:12
svnrevision: 18625
Class-Path: spring-ws-core-1.5.6.jar spring-aop-2.5.6.jar spring-
 web-2.5.6.jar spring-webmvc-2.5.6.jar spring-context-support-2.5.6.jar
.. .. ..

 

Thanks to the usage of Manifest, You will

  • Never come across any jar file with a version that is not identified,
  • Never ask anymore when it was build (buildDate) and where (Built-By helpful if you have distributed build server agent) with what (svnrevision)
  • Never try to guess what was in the class path.

Lets add a bit of “magic” in one of our pom.xml, I assume that you have crafted a pom hierarchy using pom inheritance, isn't’ it? so this code may have it’s place in your organization wide super pom.

The first plugin “buildnumber-maven-plugin” is unfortunately required, as it is the only way to get the revision number of the each Maven module. This is a small plugin that will get for each module the SVN revision and publish it under a variable ${buildNumber}

<plugin>
    <groupid>org.codehaus.mojo</groupid>
    <artifactid>buildnumber-maven-plugin</artifactid>
    <version>1.0-beta-3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>create</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <docheck>true</docheck>
        <doupdate>true</doupdate>
    </configuration>
</plugin>

Configure the “maven-jar-plugin” to create manifest entries. Note the 2 custom entries svnrevision, that use the system variable published  by the maven plugin “buildnumber-maven-plugin” and builddate. These 2 variable will also be read later in java.

<plugin>
    <groupid>org.apache.maven.plugins</groupid>
    <artifactid>maven-jar-plugin</artifactid>
    <version>2.2</version>
    <executions>
        <execution>
            <goals>
                <goal>jar</goal>
                <goal>test-jar</goal>
            </goals>
            <phase>package</phase>
        </execution>
    </executions>
    <configuration>
        <archive>
            <manifest>
                <addclasspath>true</addclasspath>
                <adddefaultimplementationentries>true</adddefaultimplementationentries>
                <adddefaultspecificationentries>true</adddefaultspecificationentries>
            </manifest>
            <manifestentries>
                <svnrevision>${buildNumber}</svnrevision>
                <builddate>${maven.build.timestamp}</builddate>
            </manifestentries>
        </archive>
    </configuration>
</plugin>

 

and don’t forget to also update your “maven-war-plugin” archiver

<plugin>
    <groupid>org.apache.maven.plugins</groupid>
    <artifactid>maven-war-plugin</artifactid>
    <version>2.1</version>
    <configuration>
        <archive>
            <manifest>
                <addclasspath>true</addclasspath>
                <adddefaultimplementationentries>true</adddefaultimplementationentries>
                <adddefaultspecificationentries>true</adddefaultspecificationentries>
            </manifest>
            <manifestentries>
                <svnrevision>${buildNumber}</svnrevision>
                <builddate>${maven.build.timestamp}</builddate>
            </manifestentries>
        </archive>
    </configuration>
</plugin>

 

The next time you run a “mvn package” on your project, or multi module project, all jar and war will get their MANIFEST.MF filled up by Apache Maven.

To solve problem number 2,

When you are using guerilla testing techniques  (describe rapid iterations of user testing with few users) You expect the testing team:

  • to deliver some quality bugs reports.
  • to receive as much information as possible to be able to crush bugs efficiently.

 

IN order to reach that objective, I propose you to display in the bottom part of your web application some interesting data that will hopefully be part of any decent screenshot attached to bug entries.

1.0.0-SNAPSHOT 2010.09.22 15:43:23 16789 2010.09.22 17:12:53
The sprint version or Maven version timestamp when Maven did build that version SVN revision number of the web artifact timestamp when the page has leaved the server.

While this seems a lot of data (you can use a smaller font as long as you can read it in screenshots), you will see that they are quite useful…

  • The first one let you visually notice in which sprint the error has been reported, detect that it was not deployed, or tested on the wrong server… Selenium automatic screenshot reporting will also help you locate the version where the issue occur a lot faster.
  • The second one, the build timestamp let the testing team see when the application has been build, developer see that it has been successfully deployed,
  • The SVN revision number if the key to quickly set up an eclipse workspace with that faulty code
  • The last one, let developer find in the logs files the issue a lot more faster

To do this, all you have to do is to read the META-INF/MANIFEST.MF of your web project and write in your JSP/JSF application. Here is a Bean that is doing that

public class Version {

  private static final String IMPLEMENTATION_BUILD = "Implementation-Build";
  private static final String IMPLEMENTATION_VERSION = "Implementation-Version";
  private static final String BUILDDATE = "buildDate";
  private static final String SVNREVISION = "svnrevision";

  private static final String META_INF_MANIFEST_MF = "META-INF/MANIFEST.MF";

  public String getVersion() {

    Manifest mf = new Manifest();
    try {
      //Icefaces
String appServerHome =
CoreUtils.getRealPath(FacesContext.getCurrentInstance(), "/");
//Spring
//String appServerHome =
//FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance())
File manifestFile = new File(appServerHome, META_INF_MANIFEST_MF); mf.read(new FileInputStream(manifestFile)); Attributes mainAttributes = mf.getMainAttributes(); String version =
String.valueOf(mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION)); String buildDate = String.valueOf(mainAttributes.getValue(BUILDDATE)); String svnrevision = String.valueOf(mainAttributes.getValue(SVNREVISION)); return "" + version + " " + buildDate + " " + svnrevision + " "
+ (new Date()).toString(); } catch (Exception e) { } return ""; } }

 

Put something like this in all your XHTML views

<span class=”developerFooter”>#{Version.version}</span>

 

And voila!

I recommend you also to switch this display off when you ship your software to your customers

comments powered by Disqus

You might like also

Fetching artifact programmatically through REST/API in Nexus 3.x
There is so many case where it is desirable to pull down artifact from Sonatype Nexus using REST API, unfortunately Nexus 3.x Rest API are still under development... Some use cases in Nexus 2.x: You have a script that uses REST call to pull down the LATEST maven artifacts every night from Nexus and deploys them. You make extensive use of the REST API in all your puppet modules You use the Atlassian Puppet module for Nexus for creating repository, …
723 Days ago
git-branch-renamer-maven-plugin
When working with many feature/release/bugix/hotfix branches, it is a bad idea to start changing the pom version as this will create merge conflicts using pull request. this plugin allow you to keep in ALL branches the same pom version for all your projects, for example MASTER-SNAPSHOT the version will be derived from branch name automagically :-) You may want to read more first these 2 short articles Update Maven pom version on GIT checkout in TeamCity maven-release-plugin with GIT git-branch-renamer-maven-plugin …
735 Days ago
Review: Getting Started with Apache Maven by Russell Gold
Some time ago I was asked if I would like to write a review about one of the new video courses from Packt Publishing. It was "Getting Started with Apache Maven" http://bit.ly/1fycmpP by Russell Gold and since I have been using Maven for some years now (since 2007) and did publish some articles myself, I thought it would be nice to help them promote Apache Maven. The course is organized in eight chapters, forty videos with a length between two …
1922 Days ago
Update Maven pom version on GIT checkout in TeamCity
Here is a solution to the following problems Deriving Maven artifact version from GIT branch, Update pom version on GIT checkout automatically, Add the ability to use Pull request with Apache Maven. You have a workflow requirement that require you to have the artifact version of a module externally defined from the current branch in GIT. For example You want to start working on a new feature branch “feature-memory-improvement”, so you branch from master a new branch named feature/feature-memory-improvement Having …
1927 Days ago
Easily Compress Web Application Resources with EhCache
Resources such as JavaScript and CSS files can be compressed before being sent to the browser, improving network efficiencies and application load time in certain case. If you are not using Apache with mod_deflate or nginx in front of your web application, you may need to implement resources compression yourself…. Wait! don’t start writing your own filter to compress files like CSS, html, txt, javascript it is way more difficult than you think to properly handle http response headers and …
2409 Days ago
Tomcat 7 and Apache Maven
Here is 3 different way to control the lifetime a local Tomcat 7 container using Apache Maven. A typical scenario would be to start a servlet container prior to running integration tests (Selenium, SAHI or using any other framework you can think of ) With the following examples, you will be able to start an instance of Tomcat 7 running your web application in the pre-integration-test phase and stop the instance in the post-integration-test phase. You can also decide to …
2409 Days ago
Apache Maven copy local file to a remote server server using SSH
I will show you in an Apache Maven configuration file how to copy files to server each time the package phase is executed. Solution with Ant SCP task This snippet of code is a ready to use code that make use of Apache Ant task scp, Just put this snippet of code in your Maven module where the assembly is executed or anywhere else to push all tar.gz files to a server just run a maven mvn package, you can …
2597 Days ago
Apache M2Eclipse: Get rid of Duplicate resources when opening resources and types
In this small post, I’ll show you how to remove duplicated resources in the Open Resource view of Eclipse Eclipse – M2Eclipse – Subversive …
2603 Days ago
Apache Maven 3 Cookbook
&160; First a big thanks to Packt Publishing for having sent me this book to review! I did enjoy going through this book, while I did not learn a lot of new stuff (I am using Apache Maven daily since 2006!), I found it to be concise and would recommend it anytime to any of my colleagues. But let’s go through my review of this cookbook of over 50 recipes towards optimal Java Software Engineering with Maven 3: Apache Maven
2745 Days ago
Apache Maven 3 Cookbook Review
Thanks to Packt Publishing for having sent me this book to review. I will publish a review in the next coming days Grasp the fundamentals and extend Apache Maven 3 to meet your needs Implement engineering practices in your application development process with Apache Maven Collaboration techniques for Agile teams with Apache Maven Use Apache Maven with Java, Enterprise Frameworks, and various other cutting-edge technologies Develop for Google Web Toolkit, Google App Engine, and Android Platforms using Apache Maven You …
2791 Days ago