Just recently I read a blog post about a combination of technologies and how they work together. One thing that struck me though was that the webapp was configured on build time, meaning the artifact that was produced was only capable of being deployed to the environment it was built for.
During a normal project lifecycle an artifact, in this case a java webapp, will be deployed to test, stage and live respectively. If UAT is completed on stage and we’d like to take it to the next step it would have to build again with the correct settings to run on live.
Over the past years I have been involved in projects that have broken with this “tradition” and adopted a build once and run anywhere approach. In a nutshell the configuration for all environments are included in the artifact that is built. Once deployed the artifact/webapp determines what environment it is running on from a system variable or other mechanism and loads the configuration accordingly. The use of a hierarchical structure of properties allows a per environment override of base properties. The base configuration holds all the shared settings that should not differ between environments. A good example of a per environment setting is a database connection string.
db.user=username db.pass=password db.url=jdbc:myslq://host:port/dbname
As you can see only the property that is different between environments is actually added to the environment configuration file. During application startup the app.properties is loaded first followed by the properties file that is dictated by the environment setting.
This pattern is not new at all. The folks using PHP/Zend Framework do it, not to mention the folks using RoR and I am sure I have left out a few more… It just seems that everyone on the Maven bandwagon seems to have missed this way of doing things and make heavy use of maven profiles during the build process and in doing so force themselves to build for every environment they deploy to, and in doing so introduce the possibility of more things that can go wrong. The webapp that was UA tested on stage is not the same build that is deployed to live…
To sum up, if you build once, chances are, once the deployment has been tested on one environment, it’ll be ready for the others as well, without having to go through an extra build again.