Maven: Create a simple build number

It’s always a good idea to have means to integrate a build number within your application. It makes it easy to find out which exact versions are deployed on your stages our what version you’re users are running in case of third level support.

The task of creating unique build numbers can easily be automated using maven.

A build number can contain all kind of information, like the application version, a sequential number, SCM revision or a time stamp.

From my point of view, using the time stamp when creating a unique build number is essential: It is unique per se (it is unlikely that the same system is build twice in one second) and it is generated by maven without depending on any plugins. In addition, it is easy to understand, like “Did operations really deploy the new version of the application, yet? No, the build number still shows that it’s the one from last week!”.

So let’s get to buisness: How to generate build numbers within a JAR and how to read it? Does it also work with WARs?

JAR

As mentioned before, maven provides a built-in mechanism for creating a timestamp. You can just customize the formatting and use it for your build number within your pom.xml like so:

	<properties>
		<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
		<buildNumber>v.${project.version} build ${maven.build.timestamp}</buildNumber>
	</properties>

Please note that using the property maven.build.timestamp directly within your filtered file is not possible due to this bug.

The build number must no be made accessible to your application. There are at least two solutions at hand: Write the build number to your manifest or create a properties file.

Manifest

pom.xml

	<build>
		<!-- Add build number to manifest -->
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<manifestEntries>
							<build>${buildNumber}</build>
						</manifestEntries>
						<manifest>
							<mainClass>info.schnatterer.Main</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build>

And that’s how you can access it from your application:

	private String getBuildNumberFromManifest() throws IOException {
		InputStream manifestStream = getClass().getClassLoader()
				.getResourceAsStream("META-INF/MANIFEST.MF");
		if (manifestStream != null) {
			Manifest manifest = new Manifest(manifestStream);
			Attributes attributes = manifest.getMainAttributes();
			return attributes.getValue("build");
		}
		return null;
	}

Properties

Alternatively, create use a properties file:

build.properties

buildNumber=${buildNumber}

pom.xml

	<build>
		<resources>
			<resource>
				<!-- Filter for build number -->
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
				<includes>
					<include>build.properties</include>
				</includes>
			</resource>
		</resources>
	</build>

And that’s how you can access it from your application:

	private String getBuildNumberFromProps() throws IOException {
		String propertiesName = "/build.properties";

		InputStream propertiesStream = Main.class
				.getResourceAsStream(propertiesName);
		if (propertiesStream != null) {
			Properties pros = new Properties();
			pros.load(propertiesStream);

			return pros.getProperty("buildNumber");
		}
		return null;
	}

The output looks something like this:

v.0.0.1-SNAPSHOT build 20140225211328

Note: You might want to check the returned value for null or have the methods return empty Strings in order to avoid NullPointerExceptions or the word null on your GUI.

WAR

If you’re building a web application, you should also be able to use the manifest or the properties file as described above. Your maven set up might be a bit different, though (see Maven War plugin – WAR Manifest Customization).

You have another alternative that makes creating the build number even easier: You can “stamp” the build number directly into interpreted documents like (X)HTML or js files.

For example when using JSF, you could write the build number directly into the footer template.

Add this to your page:

<h:outputText styleClass="version" value="${buildNumber}"/>

And this to your pom.xml

	<properties>
		<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
		<buildNumber>v.${project.version} build ${maven.build.timestamp}</buildNumber>
	</properties>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<!-- Filter for build number -->
					<webResources>
						<resource>
							<directory>src/main/webapp/WEB-INF/templates</directory>
							<targetPath>WEB-INF/templates</targetPath>
							<filtering>true</filtering>
							<includes>
								<include>yourFooterTemplate.xhtml</include>
							</includes>
						</resource>
					</webResources>
				</configuration>
			</plugin>
		</plugins>
	</build>

And that’s it. No parsing necessary in code, as maven will insert the build number in your web page directly.

Further Reading

If you’re planning on creating a more complex build number (SCM, sequential numbers, etc.), I suggest you have a look at the Build Number Maven Plugin.

Advertisements

JSF: Displaying FacesMessages during render response phase

The problem

A controller runs into an error situation during the last phase of the JSF lifecycle (the RENDER_RESPONSE phase). In order to let the user know that something went wrong, a FacesMessage is added. However, the faces message is not shown on the client. There may or may not be a warning on the log which says “FacesMessage(s) have been enqueued, but may not have been displayed“.

The cause

In the render response phase the component tree is traversed and each component is rendered (that is, HTML is generated). When an error occurs after the message component finished rendering, it is not possible to add another message to it.

Some solutions/workarounds

  1. Place the message component at the end of the component tree (that is, the page or template). That way, it’s most likely that the message widget has not been rendered at the time the content is rendered (which is when the error occurs and the FacesMessage is added). The FacesMessages are processed later, when the message widget is rendered.
    However, in most cases you don’t want to display your message at the end of the page. This can be solved with at least these two approaches:

    1. Use an overlay (for example PrimeFace’s growl widget – <p:growl>), whose position on the rendered page is “independent” of its position in the component tree.
    2. Move the widget via CSS positioning (which is a bit of an ugly workaround).
  2. Try to validate the data in an earlier phase. For example, you could check the data before rendering via an event:
    <f:event type="preRenderView" listener="#{bean.initData}"/>
    

    Or (if you’re using Seam), you could use Seam page actions,  as shown in this thread.

  3. Save the messages in the session and trigger a server render (which can be done with ICEfaces). This can be realized with a PhaseListener as described here.

Which one to use?

This depends on your use case and the component framework you’re using.

Solution #3 should always be your last measure, as it is really heavyweight and it requires additional HTTP requests.

#2 cannot be used in conjunction with some components and requires changing the UI logic and increases complexity of your code.

Which leaves #1, which is the most pragmatic solution. However, it can’t be used when your FacesMessage should be displayed on a position within the page (e.g. on the top of the page).

An example

When rendering data using PrimeFace’s DataTable with lazy loading (p:dataTable) the data is fetched from database via the LazyDataModel at rendering time (render repsonse phase). Once the data is fetched it might occur that some data is missing and the user should be informed about this fact. In order to do so, a FacesMessage would be the way to go. However, as described above, the message never gets rendered.

As far as I know, fetching the data cannot be brought forward to an earlier phase.

As the growl widget was already used within the application as the way of displaying information to the user, the solution was as easy to move the growl widgets to the end of the layout template. And voilà, the messages suddenly show up!

This solution was really easy to realize, but finding out about it took a painful amount of time. So hopefully, this post may speed up the process for anyone stuck with the same problem 🙂