Friday, December 9, 2011

Reading a properties file, in an Axis2 web service, from the file system...

For those with some experience with Axis2 web services, you know that the axis2 application gets installed, as all Tomcat applications, in the <TOMCAT_ROOT>/webapps directory.

The axis2 app itself has a WEB-INF sub-directory, which itself contains these :

- classes
- conf
- lib
- modules
- services

I've been coding a few web services lately which use some java libraries (jars). I've found that the easiest way for the web services to get access to those libraries is to install all these jars in the WEB-INF/lib directory.

I then came to this requirement : one of the classes in one of the libraries needed to get its configuration information from a Properties file.

When I was coding within the Eclipse environment, that was easy enough, I just put the configuration file in my Eclipse project's root, and then used the following code :

String filename = "config.properties";
Properties props = new Properties();
props.load(new FileInputStream(filename));

Nothing new here, and it worked like a charm.

The problems started when I packaged that class into a library, and tried to use it from some web service installed in Axis2. The file couldn't be found anymore, or, more precisely, I had no idea where to put the file.

Note that I didn't want to put the file within the AAR archive : I wanted the file to be outside the web service's archive because I wanted to configure the application from a text file that could be easily changed with a text editor directly on the target server. I wanted to avoid having to rebuild the archive everytime I wanted to install somewhere where I needed different properties.

It turns out that all that's needed is this :

- put your properties file in the WEB-INF/classes directory or your Axis2 installation, or to be more precise, in <TOMCAT_ROOT>/webapps/axis2/WEB-INF/classes
- in your code, use this.getClass().getResourceAsStream(), like this :

String filename = "config.properties";
Properties props = new Properties();
InputStream isr = this.getClass().getResourceAsStream("/"+filename);
if (isr != null){
  InputStreamReader isrProperties = new InputStreamReader(isr);
  props.load(isrProperties); 
}

Did you notice the "/" in front of the filename on the third line ?

This means look in the root of the classpath. And the root of the classpath, in an Axis2 web service environment, is <TOMCAT_ROOT>/webapps/axis2/WEB-INF/classes.

Hope this helps.