Once in the classpath, the property files and the properties they contain can be retrieved within any of the applications contained in the Mule ESB project. The code in Listing 12 will load all properties accessible from the classpath.

In conclusion

In this article we've walked through the steps to develop an environment-aware Maven build process. The resulting Maven project contains all of the properties and property-file templates for all of your Java applications, and is useable by all your Java applications for any target environment. The benefits to using this architecture are as follows:

Environment properties are centralized into a single project (App-Config), making them easier to manage over the lifespan of Java projects that use them.

Building software for multiple environments is as easy as providing a variable to the build process; e.g., –Denvironment.name=test.

All of the property files used within the final deployable artifact (ZIP/WAR), once exploded, are not contained within individual JARs. This enables developers and administrators to easily access and modify them.

It's easy to add property files that must be included in some environments but not others. This feature may be useful if you interact with differing systems in each environment.

This last feature of the environment-aware build process is particularly useful. For example, your development environment might not require a failover server, but your test environment might. If your code handled the failover process, you could clone your primary server’s property file and simply modify the property values to reflect the redundant server. That cloned property file would then be used to connect to the redundant server when conditions were appropriate for failover.

Since your development environment does not need this extra property file but your test environment does, you can simply clone the correct property file template in the App-Config project, but only in the test directory tree, and configure it with the failover server connection information.

There are some downsides to this architecture, which are also worth noting:

Whenever a new property file is added to an application, the property file must be templatized and added to the App-Config project in each directory tree (dev,test,prod). In addition, the project’s pom.xml must be modified so that the property file is copied to target/conf.

Every Maven project you build will be dependent on two other Maven projects: Parent-POM and App-Config. Projects will therefore not be self-contained with respect to the build process. This is somewhat mitigated by setting up a shared Maven repository for your projects, such as Archiva. The build process would then use the shared repository to find the App-Config and Parent-POM artifacts.

During the clean phase, each project has a copy of every property file, property key, and property value for all environments in its target/alternate-resources directory. In practice, this has not been shown to cause any significant performance degradation, but it's still not ideal.

I believe the benefits of the environment-aware Maven build process (that is, having a uniform strategy and solution for managing all properties across environments for every Java project) outweigh its few downsides. You are welcome to download the source files that come along with this project and use them to set up your own environment-aware build process.

Paul Spinelli is currently CTO of the San Diego-based startup Tactical Edge. Since graduating from the University of Virginia with a bachelor's degree in computer science, Paul has worked as a software developer for over 13 years. His experience has brought him an in-depth knowledge of various programming languages, OOP techniques, and security technologies.