/ SOFTWARE ENGINEERING, VERSIONING

What's the version of my deployed application?

In my career, I’ve noticed many small and un-expensive features that didn’t find their way into the Sprint backlog because they didn’t provide business value. However, they provided plenty of ROI during the life of the application, but that was completely overlooked due to short-sighted objectives (set by short-sighted management). Those include, but are not limited to:

  • Monitoring in general, and more specifically metrics, health checks, etc. Spare 5 days now and spend 10 times that later (or more…​) that because you don’t know how your application works.
  • Environment data e.g. development, test, production, etc. It’s especially effective when it’s associated with a coloured banner dependent on the environment. If you don’t do that, I’m not responsible if I just deleted all your production data from the last 10 days because I thought it was the test environment. This is quite easy, especially if login/passwords are the same for all environments - yes, LDAP setup is complex so let’s have only one.
  • Application build data, most importantly the version number, and if possible the build number and the build time. Having to SSH into the server (if possible at all) or search the Wiki (if it’s up-to-date, a most unlikely occurence) to have to know the version is quite cumbersome when you need the info right now.

Among them, I believe the most basic one is the latter. We are used to check the About dialog in desktop applications, but unless you deliver many (many many) times a day, those are necessary for any real-world enterprise-grade application. In the realm of SOA and micro-services, it means this info should also be part of responses.

With Maven, it’s quite easy to achieve, this as a simple properties file only is needed and the maven-resource-plugin will work its magic. Maven provides a filtering features, meaning any resource can be set placeholders and they will be replaced by their values at build-time. Filtering is not enabled by default. To activate it, the following snippet will do:

<project...>
    <build>
        <resources>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

I wrote about placeholders above but I didn’t specify which. Simple, any data set in the POM - as well as a few special ones, can be used as placeholders. Just use the DOM path, inside $ and brackets, like that: ${dom.path}.

Here’s an example, with a property file:

application.version=${project.version}
build.date=${maven.build.timestamp}

If this snippet is put in a file inside the src/main/resources directory, Maven will generate a file named similarly with the values filtered inside the target/classes directory just after the process-resources. Specific values depends of course on the POM, but here’s a sample output:

application.version=1.0.0-SNAPSHOT
build.date=20150303-1335

Things are unfortunately not as straightforward, as there’s a bug in Maven regarding ${maven.build.timestamp}. It cannot be filtered directly and requires adding an indirection level:

<project...>
    <build>
        <properties>
            <build.timestamp>${maven.build.timestamp}</build.timestamp>
        </properties>
        <resources>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

The following properties file will now work as expected:

application.version=${project.version}
build.date=${build.timestamp}

At this point, it’s just a matter of reading this property file when required. This includes:

In webapps
  • Provide a dedicated About page, as in desktop applications. I’ve rarely seen that, and never implemented it
  • Add a footer with the info. For added user-friendliness, set the text color to the background color, so that users are not disturbed by the info. Only people who know (or a curious) can access that - it’s not confidential anyway.
In services

Whether SOAP or REST, XML or JSON, there are also a few options:

  • As a dedicated service endpoint (e.g. /about or /version). This is the simplest to implement. It’s even better if the same endpoint is used throughout the organization.
  • As additional info on all endpoints. This is required when each endpoint can be built separately and assembled. The easiest path then is to put it in HTTP headers, while harder is to put it in the data. The latter will probably require some interceptor approach as well as an operation on the schema (if any).

There are two additional options:

  1. To differentiate between snapshot versions, use the Maven Build Number plugin. I have no experience of actual usage. However, it requires correct configuration of SCM information.
  2. Some applications not only display version information but also environment environment information (e.g. development, integration, staging, etc.). I’ve seen it used either through a specific banner or through background color. This requires a dedicated Java property set at JVM launch time or an system environment variable.

The filtering stuff can be done in 1 hour max in a greenfield environment. The cost of using the data is more variable, but in a simple webapp footer case, it can be done in less than a day. Compare that to the time lost getting the version during the lifetime of the application…​

Nicolas Fränkel

Nicolas Fränkel

Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Also double as a trainer and triples as a book author.

Read More
What's the version of my deployed application?
Share this