Null Pointer


Sometimes you have to be evil!

By debashish • Jan 2nd, 2004 • Category: Technology

Many times the most innocuous aspects of programming create lot of trouble. Take the innocent Properties file. These avatars of Hashtable are collections of key-value pairs, frequently used by applications for their need for external resources and configuration settings. Now pointers such as these tell you that reading the Properties file using java I/O is evil, owing to the fact that it warrants absolute file names and that in turn hinders application portability. So we have the recommended ways to use the ResourceBundle class or classpath resources. Nothing wrong with this!

Or so I thought, till I had to work on a web-interface to create, modify and delete Properties files. I realized that when loading a Properties file using the Classloader and ResourceBundle and after I modify my files and store() the values, the changes though successfully saved to the file in question won't reflect to the user. The old properties were displayed despite the fact that some of them had been changed. The reason it seems was the fact that the classloader somehow cached the Properties. While this would be termed most efficient and desirable when reading the properties, this perhaps wouldn't be so in an Property File Editor application like mine.

In a nutshell what I ultimately had to do was to take the evil route and use java.io to load the files, as below:

//Do not load the properties file as Resource stream or ResourceBundle
//if caching is not acceptable
//InputStream in = loader.getResourceAsStream(name);

//Load it using direct I/O, obviously we need the file “path” here, which can be
//retrieved using the ServletContext
in = new FileInputStream(path);

//rest is usual
if (in != null) {
 Properties objProps = new Properties();
 objProps.load(in);
}

Since this is a web-application I am fetching the relative file-path of the Properties file (situated along with other classes in a package structure) using the ServletContext (getRealPath()), this works well in Tomcat, I am not sure if this approach works for all containers, especially on Websphere.

Update (Jan.01, 2004):

I must apologise for not updating this post after I implemented Anthony's suggestion based on the original post (see comments on this post). The getResourceAsStream() approach is indeed cool to load the file without using classloader while avoiding risk of unpredictability associated with getRealPath() on various containers. This also avoided the caching that the classloader was doing. So the code above may be revised as follows:

//Do not load the properties file as Resource stream or
//ResourceBundle if caching is not acceptable
//InputStream in = loader.getResourceAsStream(name);

//Load it using direct I/O, obviously we need the file “path” here,
//which can be retrieved using the ServletContext
String path = “/WEB-INF/properties/” + name + “.properties”; //say

//getResourceAsStream() does not use classloader
in = sContext.getResourceAsStream(path);

if (in != null) {
 Properties objProps = new Properties();
 objProps.load(in);
}

Tagged as:

Author: debashish
More details about Debashish are here.
All Posts by debashish

2 Responses »

  1. Any use of getRealPath() will most likely not work if you use unpacked WARs. Perhaps you should try using ServletContext.getResourceAsStream() instead of the class loader method.

  2. Did you update the original file?
    Did you re-load file?
    Did you flush()?
    Try using Dynamic properties:
    http://www.javaworld.com/javaworld/javatips/jw-javatip125.html?

Leave a Reply