I have a web application. I’m configuring CI for it.
We didn’t use a build tool (neither Ant nor Maven), and made builds by means of IDE.
Now I’m working on an Ant script which will be used by our build system.
There are several property files which should have different properties’ values when the project is build on the build server but not on local machines.
What are the common approaches for handling such situation?
If we used Maven, I would probably go with using different profiles, but we have Ant.
One possible solution which I can see is creating a root folder for all property files sets, and storing each set in a separate subfolder (see the schema below).
/profiles
/dev1
prop1.properties
prop2.properties
/dev2
prop1.properties
prop2.properties
/build-server
prop1.properties
prop2.properties
/webapp
/WEB-INF
Then during the Ant build we can copy the correct set to the correct location. But it can be a problem to make builds by IDE as we used to do (because property files are not stored in their proper place under src folder any more).
Are there any other approaches?
If I understand you, you build separate ear/war/jars for each and every environment on your continuous build server. Is that correct?
I have two ways I handle this: The Smart Way, and the Dumb Way:
Smart Way
The smart way is to configure your application server (JBoss, Weblogic, etc.) to look for the desired property file external to the jar/ear/wars that are installed in the application server. This way, you build one set of jar/ear/wars, and it works everywhere. Plus, you do something very, very important: You cause the Finger O’ Blame to point elsewhere.
If the properties files are packaged as part of the jar/ear/war, and something on the server changed, you’d get the blame because the your build was bad. Sure, you had no way of knowing the they changed the environment, but you did install that bad build file on the production server.
However, if the properties are stored outside of the build artifact, then it’s the team responsible for configuring the servers that’s at fault.
Actually, it’s a lot easier for the team responsible for configuring the application server to handle the issue. They know what got changed, and they can update the properties file to reflect that change. Not only that, but you’re only having to build and distribute a single set of artifacts. You don’t have to worry if a new environment is setup, of if something in the old environment changes. In fact, changes can easily take place without forcing you to do a new release.
Dumb Way
We were able to do things the Smart Way at my last company. At my current company, we do things the Dumb Way. The properties are embedded in our build artifact, and there is no easy way to change it.
I divided each set of properties files by suffix instead of different directories (i.e build.properties.dev1, build.properties.dev2, etc). We placed properties files were put in a single directory.
When I do a build, I use the AntContrib
<for>task to loop through the build process multiple times, each time with a different properties file. I then build an artifact for each and every set of properties files. I use the suffix on the properties file as folder names in mytargetdirectory where I store the built artifacts. That way, each build produces all the artifacts for all the environment.That way, if the artifact worked in the dev environment, it will work in QA and Production. The only problem is that I’m storing 5 to 10 times the number of artifacts on my Jenkins server, so I need 5 to 10 times the disk space.
By the way, as long as I can define a
<fileset>to find the properties files, I can use the<for>task, so you can use the different directories. And, you can use<basename>to pluck off the directory names.