Monday, October 29, 2007

ZoneInfo error ?



I ran into this error some time back when I was loading a Sybase driver into my application code using Class.forName()

ZoneInfo: null\lib\zi\ZoneInfoMappings (The system cannot find the path specified)

Analysis of the stack trace revealed that the system seemed to be trying to find out what time zone my JVM belonged to. The trace also mentioned that it was unable to find java.home. This was quite weird since my computer was in the right time zone and the java.home property was not set anywhere in my code or the eclipse runtime property set.

After searching for a while I found out where the problem was. I was loading some properties into my system properties and while loading my properties the JVM wiped out the existing properties, thus creating the error. I wanted to use the name value pairs inside a .properties file and then have my application look up a system property every time it needed a configuration detail. Here was the problem

Not so good code:

java.util.Properties props = new java.util.Properties();
props.load(new FileInputStream(new File(fileName)));
System.setProperties(props); // Dont do this.

The System.setProperties(props) method wiped out existing properties (like java.home or time zone information ) and wrote my properties into the system properties. I got around the problem by setting the system properties one by one in a loop using the System.setProperty() method.

Better code:

Iterator iterator = props.keySet().iterator();
while(iterator.hasNext())
{
String key = iterator.next().toString();
String value = props.getProperty(key);
System.out.println(key + " " + value);
System.setProperty(key,value);
}

However the approach shown above can be inefficient and spans a couple of lines as well. The Properties class extends from the Hashtable class thus making it a Map. The following code can be used to add properties to existing system properties in the best way possible.

Best code:

java.util.Properties props = new java.util.Properties();
props.load(new FileInputStream(new File(fileName)));
System.getProperties().putAll(properties); // Does not replace existing property keys in system properties but will rather replace their values alone, if they already exist.

I should also mention that this problem is not always consistent. Sometimes the JVM wipes out the existing properties and other times it does not. With JDK 1.3.1 hosted on windows 2000 server I received this error but with JDK 1.5 and windows XP this error does not occur. Perhaps it was fixed in JDK 1.5 or the environment plays a role here. However it is better to avoid such random behavior if we are to write production quality code

You might also want to consider saving an instance of the Properties class or loading the name value pairs into a resource bundle in case you do not want to load runtime configuration into a system property..

No comments: