SDLC tracebility is the king
One of the most important thing during the SDLC (for sure apart from the other stuff) is to keep control over deployed artifacts to all environments at any given time. Lack of control leads to chaos and generates a lot of extra work to the team, degrades throughput, morale and motivation. No need to even mention that arguments among team members regarding deployed features or fixes definitely do not contribute well to the team spirit.
Trace build artefacts
One of the common approaches mitigating this risk is generating a build number to every single build fully automatically. Let’s take a look at how to accomplish this in common project set up – maven project build on build server e.g. TeamCIty. Sample web application follows.
Generate meta information in MANIFEST.MF
Common place where to store such kind of info is MANIFEST.MF file. All kind of archives have this file located in /META-INF/MANIFEST.MF. Various technologies like OSGi use this location for various metadata. Taking advantage of maven-war-plugin the content of MANIFEST.MF can be easily customized as follows (${xx} are maven variables):
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: ${user.name} Build-Jdk: ${java.version} Specification-Title: ${project.name} Specification-Version: ${project.version} Specification-Vendor: ${project.organization.name} Implementation-Title: ${project.name} Implementation-Version: ${project.version} Implementation-Vendor-Id: ${project.groupId} Implementation-Vendor: ${project.organization.name}Setup maven pom
To set up a maven project pom file is pretty easy:
org.apache.maven.plugins maven-war-plugin true true ${build.number}Where build.number variable gets supplied by build server in arbitrary format, e.g. for TeamCity build server:
Build number is visible in build queue status page as well:Create a version page
To access these project build specific information simple jsp page can be created:The controller accessing these information using Spring MVC (simplified example) can look like:@Controller public class ProjectInfoController { @RequestMapping("/info") public ModelAndView getProjectInfo(HttpServletRequest request, HttpServletResponse response) throws IOException { ModelAndView modelAndView = new ModelAndView("projectInfoView"); ServletContext servletContext = request.getSession().getServletContext(); Properties properties = new Properties(); InputStream is = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF"); properties.load(is); modelAndView.addObject("buildBy",properties.getProperty("Built-By")); modelAndView.addObject("buildJdk",properties.getProperty("Build-Jdk")); modelAndView.addObject("specificationVersion",properties.getProperty("Specification-Version")); modelAndView.addObject("specificationTitle",properties.getProperty("Specification-Title")); modelAndView.addObject("implementationVendor",properties.getProperty("Implementation-Vendor-Id")); modelAndView.addObject("buildNumber",properties.getProperty("Build-Number")); return modelAndView; } }Accessing MANIFEST.MF in JAR file has a different approach. Motivation taken from Spring source code:
Package package = someClass.getPackage( ); String version = package.getImplementationVersion();JSP page or other presentation layer shouldn’t be a problem for anyone.
Thank you for this detailed post – it worked for me :). Specifically, I am build a JAR and not a WAR so I replaced “maven-war-plugin” with “maven-jar-plugin”.
LikeLike