Environment specific configuration for Java applications
August 14th, 2009 in Java/J2EE. Add commentIn the course of the development lifecycle, most enterprise java applications are deployed in several environments. Therefore environment specific values like database connection strings, web service end points etc. that are usually put in a properties file must be changed from environment to environment. We discuss here a few methods for automatically changing these values in the properties files with values specific to the environment.
Method 1: Using the ant copy task
This is the easiest and most straightforward way. Assume that the properties file is named application.properties and is located at webapp/WEB-INF/conf/ from where it is read by the application at runtime.
- Create copies of this application.properties file for each environment and name them according to the environment i.e dev.properties, prod.properties etc for development and production respectively.
-
Then depending on the environment for which the application is being compiled for, copy the appropriate properties file to application.properties using the ant copy task:
<property name=”env.prop.file” value=”${env}.properties” />
<property name=”web-inf” value=”webapp/WEB-INF” />
…………………………………………
<copy file=”${env.prop.file}”
tofile=”${web-inf}/conf/application.properties” overwrite=”true” /> - Of course the value of ${env} will have to come from somewhere, so you will have to run ant with the proper option for example -Denv=dev, to use with dev.properties.
Drawbacks:
If your application.properties file has other properties(like error messages) that are not environment based, they will have to be unnecessarily duplicated in all your environment specific files. This might mean more work on keeping track of changes.
Also a copy task would be required for each properties file that you have.
Method 2: Using the ant replace task with filters
In this method, instead of doing a complete overwrite of the application’s properties file, only the environment specific values are replaced. Moreover, multiple files can be changed with a single replace task using this method.
-
Externalize only environment specific properties in their respective files e.g dev.properties containing development environment properties might look something like this:
db.userName= APP_USER
db.password =APP_PWD01$
db.connectionURL=jdbc:oracle:thin:@mydomain.com:1526:werfgt -
Put tokens instead of the actual values of environment specific properties in your application’s properties/configuration file(s). For example, here we have tokenized these values by the leading and trailing ‘@@’s in two files: application.properties and config.xml.
application.properties:
…………………..
…………………………
db.username=@@dbusername@@
db.password=@@dbpassword@@
db.connectionURL=@@dbconnurl@@
……………………….
……………………….config.xml:
<dbconnection>
<property name=”dbuser”>@@dbusername@@</;property>
<property name=”dbpw”>@@dbpassword@@</property>
<property name=”dbconn”>@@dbconnurl@@</property>
</dbconnection> -
Then use the ant “replace” task with replace filters as in the following:
<property name=”env.prop.file” value=”${env}.properties” />
<property name=”web-inf” value=”webapp/WEB-INF” />
…………………………………………………<replace dir=”${web-inf}/conf” propertyFile=”${env.prop.file}” >
<replacefilter
token=”@@dbusername@@” property=”db.userName” />
<replacefilter
token=”@@dbpassword@@” property=”db.password” />
<replacefilter
token=”@@dbconnurl@@” property=”db.connectionURL” />
</replace>The replace task can be interpreted as follows: for all files in the webapp/WEB-INF/conf directory replace the tokens in the following
tags with the value of the property given in the ${env}.properties file . Note how the values of the token and property attributes are taken from the two properties files; the following graphic should make it clear:
- Run ant with -Denv=dev or whatever, depending upon which environment you are building for. The tokens in config.xml and application.properties will be replaced by the actual values.
Method 3: use the replace task with the replacefilterfile attribute
The above method requires every token to be put into your ant build file. A better option would be put these tokens itself as keys in your environment specific files and let ant do the rest.
-
change your dev.properties/prod.properties to look like the following…
@@dbusername@@=myusername
@@dbpasswd@@=mypasswd
@@connurl@@=jdbc:oracle:thin:@somedomain.com:1521:abcde -
…and change the ant replace task to the following:
<replace dir=”${web-inf}/conf” replacefilterfile=”${env}.properties”>
<include name=”**/*.properties”/>
<include name=”**/*.xml”/>
</replace> - Now when you run ant (with the -D option as described above) all the tokens will be replaced with the values from the appropriate properties file.

