Mathias Kissig
Mathias Kissig

Reputation: 93

modify properties file in Tomcat during runtime

I would like to modify a properties file of a Portlet during runtime. The portlet is deployed in a Tomcat 7.0.23 and the properties file sits in "/WEB-INF/classes/content" from where I can access it via the code shown below. In fact, the code is executed without any exceptions but the newly added Property is not saved to the properties file.

String fileName = "MyProps.properties";
String relativePath = "/WEB-INF/classes/content/";
String fullPath = "c:/tomcat-7.0.23/webapps/my-portlet/WEB-INF/classes/content/";
try {
    String path = relativePath + fileName;
    InputStream in = getPortletContext().getResourceAsStream(path);
    Properties props = new Properties();
    props.load(in);
    props.setProperty("test", "test");
    File file = new File(fullPath + fileName));
    FileOutputStream out = new FileOutputStream(file);
    props.store(out, "");
} catch(Exception ex) { // error handling here}

After adding the new Property, I could verify with

props.list(System.out);

that it was added indeed. The context.xml file contains the following entries:

 antiJARLocking="true"
 antiResourceLocking="true"

Is this the right way to add/change Properties in a running Tomcat instance or should I take a different approach? If the latter, how could it be achieved best?

Many thanks for your answers!

Upvotes: 2

Views: 4822

Answers (1)

Perception
Perception

Reputation: 80593

You should definitely not rely on ever being able to change a file contained in a deployed web app. Control has been handed over to the container at that point and the file may be overwritten, or it may not even be writable. It also puts a burden on the application deployer, because now they cannot simply blow away the exploded WAR folder (if one exists) and redeploy the archive.

As an alternative to your approach, consider placing the properties file in a location external to the web app. One approach I've seen used successfully is this:

  1. Determine a 'well-known' location where runtime property files will be hosted, or allow the deployer to specify this location via a well known property.
  2. Attempt to read your property file from this location. If it does not exist, create and initialize it from a template stored within your application.
  3. Save all changes made during the applications execution to this external property file.

With this setup you never have to worry about not being able to write the file, or of it getting overwritten by the container.

Upvotes: 4

Related Questions