Phil
Phil

Reputation: 1927

Tomcat 6 / 7 - how to override a properties file within a Web Application?

I've inherited responsibility for a Web Application and the way it manages a properties file just seems wrong. The properties file is supplied within the WAR file and resides within the directory:

<tomcat>/webapps/<my web app>/WEB-INF/classes

For first-time installers of our Web Application this is fine. The default properties file has a number of default settings and having default values specified this way seems better than hard-coding the values into the Java code.

This file is ONLY read on Tomcat startup but can be updated by the running Web Application at any time.

Whenever when a customer needs to upgrade the software they must perform the following steps

  1. Stop tomcat to stop the Web Application.
  2. Make a copy of the file: foo.properties
  3. Remove the existing web application directory
  4. Deploy the new war file (purely to unpack it)
  5. Stop tomcat (again!)
  6. Copy the old foo.properties over the new one (in WEB-INF/classes)
  7. Restart tomcat.

This just seems long-winded and error prone - we often have users wipe their properties file by accident. Surely the properties file should be externalised in some manner? I like the idea of the WAR file containing the default values, but is there a way of overriding these values if another file called foo.properties is found such as on the classpath? I really want the new deploy to be:

  1. Stop the Web Application
  2. Deploy the new Web Application

and it would pick up the properties from the externalised location.

Does Tomcat supply any techniques of doing this or should I simply change the Java code to go looking elsewhere for the properties file (e.g. the user's home directory)?

Whilst writing this question I came across references to conf/catalina.properties and how this could be used to specify directories that would be read ahead of WEB-INF/classes. However modifying common.loader and shared.loader seemed to have absolutely no effect! I got this information from: http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html .

Any advice greatly appreciated.

UPDATE The properties files are being loaded in via Spring. The beans file has the following:

<value>classpath:foo.properties</value>

Now I could go and change the way that the bean that uses this properties file is instantiated and have a different loading mechanism of the properties file. But since Spring is simply looking at the classpath to obtain foo.properties it seems logical to simply put the customers properties file on the classpath.

Upvotes: 4

Views: 7659

Answers (1)

The Governor
The Governor

Reputation: 1192

If I were your customer I wouldn't like your current upgrade mechanism either. I like the idea of having properties assigned to default values, but customer can override them if they choose to. Here's one way to implement it. Have two property files default.properties and external.properties. default.properties has default values whereas the other is empty and can be used by customer. The customer simply does NOT touch default.properties. You can retain the location of the default.properties at /webapps//WEB-INF/classes. The other property file could be anywhere and you can specify that with a system property. Let's say you decide to put it at

 /home/customer/external.properties

Now change your java code so that it loads default.properties followed by external.properties. In case if a property is defined in both files then the one in external.properties gets preferred. In the file

$TOMCAT_HOME/bin/setenv.sh

declare the following environment variable

export JAVA_OPTS="-Dexternal.props=/home/customer/external.properties"

If you are on windows you declare the environment variable in setenv.bat. Now you should be able to access the external.properties file by

Properties properties = new Properties();
try {
      properties.load(new FileInputStream(System.getProperty("external.props")));
 } catch (IOException e) {
  ...
}

Upvotes: 3

Related Questions