Category Archives: Maven

How to show current version in an JBoss application

The problem

I want the current release version in my page footer on my JBoss/JSF application. After searching for a simple solution for a while I came up with something. I’m using maven to build the release version and Subversion are used as version control system. Maven have plugins for writing the pom version and svn revision number into the manifest file that end up in the war archive. The problem was to read that manifest file. The manifest file can be loaded by the ServletContext, but I did’n find a way to get hold of the context. I’m still convinced that there are a simpler solution, but as this is (another) hobby project it’s good enough.

Edit:
I found a much simpler solution to the problem of getting hold of the servlet context (link) thanx to this blog: http://www.mkyong.com/jsf2/how-to-get-servletcontext-in-jsf-2/

It’s not that obvius and a lot of ‘dot train’, but I can get rid of the listner code:

1
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

The solution

First the following plugins have to be added or updated in the pom file, in the build section, to generate the revision:

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>buildnumber-maven-plugin</artifactId>
	<version>1.2</version>
	<executions>
		<execution>
			<phase>validate</phase>
			<goals>
				<goal>create</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<doCheck>false</doCheck>
		<doUpdate>false</doUpdate>
		<useLastCommittedRevision>true</useLastCommittedRevision>
	</configuration>
</plugin>
<plugin>
	<artifactId>maven-war-plugin</artifactId>
	<version>${version.war.plugin}</version>
	<configuration>
		<!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<archive>
			<manifest>
				<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
				<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
			</manifest>
			<manifestEntries>
				<Dependencies>com.google.guava,org.slf4j</Dependencies>
				<revision>${buildNumber}</revision>
			</manifestEntries>
		</archive>
 
	</configuration>
</plugin>

Be sure to set the useLastCommittedRevision to true.

Running mvn package will genrate a war file containing a MANIFEST.MF file in the META-INF folder. The meta-inf file will contain the following version information:

revision: 12
Implementation-Version: 0.0.1-SNAPSHOT (if addDefaultImplementationEntries = true)
Specification-Version: 0.0.1-SNAPSHOT (if addDefaultSpecificationEntries=true)

Get hold of the ServletContext

With the information in the manifest file we just have to read it and show it on the page, and here it becomes a bit tricky. When running Spring on a Tomcat server I can get the ServletContext injected into my bean, but I didn’t found out how to do it on Jboss with CDI. The only way to get hold of the ServletContext was to set up an ServletContextListener and read the manifest file at application startup.

@ApplicationScoped
public class ServletContextProvider implements ServletContextListener {
	@Inject
	private Logger log;
 
	private static String version = "Unknown";
 
	@Produces
	@Named("revision")
	public String revision() {
		return version;
	}
 
	@Override
	public void contextInitialized(ServletContextEvent contextEvent) {
		ServletContext context = contextEvent.getServletContext();
		Properties prop = new Properties();
		try {
			prop.load(context.getResourceAsStream("/META-INF/MANIFEST.MF"));
			version = prop.getProperty("Implementation-Version");
			String revision = prop.getProperty("revision");
			if (revision.length() &gt; 1)
				version += " Revision:" + revision;
		} catch (IOException e) {
			log.warning("Fail to read manifest file on ServletContext:"
					+ e.getMessage());
 
		}
	}
 
	@Override
	public void contextDestroyed(ServletContextEvent contextEvent) {
		log.info("Context Destroyed");
		version = "Unknown";
	}
}

This listener have to be configured in the web.xml file (not needed with the new solution):

	<listener>
		<listener-class>se.minidev.rrdserver.util.ServletContextProvider</listener-class>
	</listener>

And at last, show it in the page! I put it into the footer in the page template: