Here are some possible practices I've used or encountered. Combining these is usually needed in practice.
Substituting the variable values in conffiles when building
Here's an example of how this can be done with Apache Ant. Ant properties (${var.name}
) can be controlled with the build configuration files:
<filterset id="variables.to.replace">
<filter token="APPNAME" value="${app.name}"/>
<filter token="WEBAPP-PATH" value="${webapp.path}"/>
<filter token="ENCRYPT-ALGORITHM" value="${encrypt.algorithm}"/>
<filter token="ERROR-MAILTO" value="${error.mailTo}"/>
<!--...-->
</filterset>
<!-- Then, when building & copying the conf, replace the variables: -->
<copy todir="${properties.target.dir}">
<!-- env specific conf files -->
<fileset dir="${basedir}/env/${run.env}/webapp/WEB-INF/classes" />
<filterset refid="variables.to.replace"/>
</copy>
The good thing is that you get a fine control over the different configurations at build time. What is bad is that the system tends to grow very complex and hard to maintain if you use this method extensively for a large number of different configurations. Also, having to build the conffiles, too, means slower development cycles.
Substituting the variables from conf inside war at webapp startup
This is what I usually do when using Spring Framework, even if there is just one possble configuration, getting the benefits of the separation of concerns. With Spring, you can have the conf values replaced with PlaceholderPropertyConfigurer inside Spring context at webapp startup. In this case, you have to anyway pick the right configuration, which can be configured for example on build time.
Compared to the build time replacing, it's easier to temporarily manipulate the values in an uncompressed webapp, if needed. Of course, the webapp needs to be rebooted if you change anything, and the manual changes won't persist across webapp redeployments. Spring is also limited to the Spring context, so this doesnt' work e.g. in web.xml (but having variables in web.xml should probably be avoided anyway because of its limitations).
Reading the local conf from a pre-defined file
This approach is probably the easiest one to set up: just invent a configuration file path, e.g. $HOME/mywebapp/conf.properties
and make your webapp somehow read it at startup.
The good thing here is that you don't have to care about the conf when building/deploying the webapp. Anyway, you should have some sensible conf defaults that can then be overridden by the local conf.
Having the conf in a database
This is the most flexible solution for overriding conf parameters, but can also get complicated in some cases. Having the conf in a table with name
and value
columns should work for the most cases.
Of course, you can't configure the JDBC connection urls in a database table, but this is a good solution for simple textual/numerical conf that affects the webapp's operation after the db connection has been set up. To avoid a performance penalty, make sure you cache the conf somehow if it will be frequently accessed.
Extra practices
As pointed out by kgiannakakis, it also helps to set up a configuration diagnosis page of some kind for your app.