Webapp versions v1.0

You should be able to determine which version of your program is running.
I think this can be illustrated by giving an example of two versions of a program:
One of these downloads is a multi-megabyte OpenGL-based warfare simulation in which theories of warfare can be tested and refined without the need for actual hostilities, including not only military but also political and social factors, seen as inextricably entwined in a realistic warfare model [1].
The other is a multi-megabyte package that will display the following dialog box:

These are, of course, two versions of the exact same piece of software; the only difference between them is that in one I’ve converted the PE COFF machine identifier to be a 7.
What I’m attempting to illustrate here is how extraordinarily brittle software is as a whole, and how knowing which version of an application an end-user is running is fairly significant when attempting to determine what the problem is at any particular point in time [2] [3].
It’s also an illustration of how pissed off I get when my State Government decides to spend over a billion Australian dollars on replacing a payroll system that worked perfectly well, but apparently no-one knew how to add a new employee to it or something. This stuff doesn’t rust, people.
Software artifacts are different from physical artifacts. In nature, you can usually break a twig without killing the tree, but this isn’t true of software, most instances of which will fall into a heap if you breathe on them the wrong way. Some developers attempt to minimise these ‘single points of failure’ by creating hideously complex design patterns, but I should probably leave that rant for another time.
Anyway, where was I.
You should be able to determine which version of your program is running.

It’s usually the first question that any IT support person will ask, because if you don’t know what version you’re running, then you don’t have a baseline from which to work out what to change to fix whatever problem you’re having [3].
If you were the sort of person who over-dramatises things, you can think of it as being similar to the fire brigade asking what building you’re in when you ring them up complaining that the air is a bit thick today. Just before they enter your address into some kind of computer system. Which is definitely working.
Microsoft desktop applications normally shove this under the Help → About dialog, command-line programs normally have a -v
or -?
switch, but webapps don’t have a standard for it.
“Yes”, you may say, “but everyone using a webapp is by definition using the same version of the webapp”, and well you might, you handsome devil you, but you haven’t considered internally-deployed webapps, or worked in a overly-bureaucratic or security-conscious organisation that considers that kind of information too difficult to retrieve or confidential, and you don’t have hundreds of the bloody things scattered over the net.
I normally allow the version information to be retrieved from /context-root/version
(where context-root is usually just “/” under the root domain), which returns a JSON map with the following keys:
bamboo.buildKey
bamboo.buildNumber
bamboo.buildPlanName
bamboo.buildTimeStamp
bamboo.buildForceCleanCheckout
bamboo.custom.cvs.last.update.time
bamboo.custom.cvs.last.update.time.label
maven.pom.name
maven.pom.version
maven.pom.groupId
maven.pom.artifactId
where the bamboo.xxxx
keys return their equivalent Bamboo global variable values, and the maven.xxxx
keys return their equivalent maven implicit property values.
You can, for example, see what happens when you click on www.randomnoun.com/version, which will tell you which version this site is currently running.
The bamboo version data is useful for DEV
and TST
environments, where I normally run snapshot artifacts, and the maven version data is useful for XPT
and PRD
environments, where I normally run full releases.
Having this information available online means that vmaint can draw the following pretty diagrams, and I can be fairly confident that it’s up-to-date:

which also provides sufficient information to query source control and provide a list of changes that will be brought in when you move one version of the webapp into a new environment:

TST
(build 93) and dmx-web in XPT
(build 47). These are the changes that will be migrated if the TST
build is migrated to XPT
.Each bullet point represents a checkin into CVS, the green ticks represent successful bamboo builds and the red exclamation mark represents a failed bamboo build.
The versioning process is part of the maven build process, and has the following moving parts:
/src/main/resoures/build.properties
com.randomnoun.common.servlet.VersionServlet
/pom.xml
fragment to filter thebuild.properties
file/src/main/webapp/WEB-INF/web.xml
to configure the servlet
Here is the contents of the build.properties
file, which should should be placed in the /src/main/resources
folder relative to the project base directory. When the project is built by maven, the expressions in ${var}
form are replaced with placeholders supplied by bamboo and maven:
And this is the VersionServlet
source, which reads the filtered form of this file and reports the values in a JSON format:
pom.xml fragment
In order to transform the build.properties
into it’s filtered form, you will need this in your pom.xml
:
<project> ... <build> ... <resources> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> <includes> <include>build.properties</include> </includes> </resource> <resource> <filtering>false</filtering> <directory>src/main/resources</directory> <excludes> <exclude>build.properties</exclude> </excludes> </resource> </resources> ... </build> ... </project> |
web.xml fragment
And in order for the VersionServlet to respond to the “/version” URI, you will need this in your /src/main/webapp/WEB-INF/web.xml
file:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4"> ... <servlet> <servlet-name>versionServlet</servlet-name> <servlet-class>com.randomnoun.common.servlet.VersionServlet</servlet-class> </servlet> ... <servlet-mapping> <servlet-name>versionServlet</servlet-name> <url-pattern>/version</url-pattern> </servlet-mapping> ... </web-app> |
So everyone start doing that, and then you’ll be able to more easily turn back time, which is what you’ll need to be able to do once Sam in accounts discovers how to modify his own payroll or something.
This class is now part in the com.randomnoun.common:common-public artifact, which can be directly referenced in your pom.xml
.
Update 2013-09-25: It’s in central now
Update 2021-01-09: It’s on github now
[2] Also, hopefully, how easy it is to get people to run programs they’ve downloaded off the internet, thereby negating the efforts of the entire software security industry. Bonus points: stop your computer from thinking about elephants.
[3] I’m assuming for the moment here that you have a problem with the software that you’re using / writing.