Environment specific configuration for Java applications

August 14th, 2009 in Java/J2EE. 4 comments
1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 3.75 out of 5)
Loading ... Loading ...

In 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@@&lt/;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:
    antreplacefilter Environment specific configuration for Java applications

  • 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.

Tags: ,

4 Responses to “Environment specific configuration for Java applications”

  1. Maxence Bonte at
    says:

    Hi,

    excellent tuto for what I think is widely searched.
    I have one more question : are properites in files located in subfolders replaced as well or not ?

    Thanks in advance.

  2. jen at
    says:

    Thanks for this! I used option 3, and it works perfectly.

  3. Sean at
    says:

    Many many thanks to you. I have searched for this almost a month in tons of websites and tried different replace options. This is so far the best of all and very useful in real work place. You are simply great!!!

  4. Ankit at
    says:

    Thats a very good approach obviously. I used it and it does fine.

    But my problem is it is done only once at the first time. And second time if i have to made a build for another environment then it doesn’t find the tokens as they are already replaced by the ant task.

    So, what should be the solution on that, could anybody suggest.

Leave a Reply

Sponsors