Loading properties files in a web application
Some times it is needed to load configuration data from properties files.
In a standard java application this could be done via
InputStream is = new FileInputStream("conf/application.properties");
java.util.Properties prop = new Properties();
prop.load(is);
is.close();The file is loaded relativ from the start directory. In a webapp container (i.e. Tomcat) the start directory is not determined and is mainly the directory where the startup script has been called. So if you directly start tomcat from the CATALINA_HOME/bin so this will also be the start directory. But one could also navigate to CATALINA_HOME and start bin/startup. So CATALINA_HOME will be the start directory.
OFF-Topic: My suggestion is to start/stop tomcat by your own scripts, which change the current directory to CATALINA_HOME or if available to CATALINA_BASE and call from there bin/startup or CATALINA_HOME/bin/startup.
For some applications and for webapps in general it is a good idea to load the configuration files from the classpath, so they could be placed in WEB-INF/classes or within one of the jars.
So it would like this:
URL url = ClassLoader.getSystemResource("conf/application.properties");
java.util.Properties prop = new Properties();
prop.load(url.openStream());But in Tomcat this won't work because of the classloader hierachy in tomcat. Every webapp has it's own classloader in tomcat. The ClassLoader.getSystemResource will use the system class loader that is used to load the bootstrap and the tomcat application. But the system class loader does not know anything about your webapp and it's classpath. Using the right class loader is essential. There are a lot of solutions to access the correct classloader (i.e. this.class.getClassLoader()). The following example will also show how to do the trick within static methods:
public class Config {
private static java.util.Properties prop = new java.util.Properties();
private static void loadProperties() {
// get class loader
ClassLoader loader = Config.class.getClassLoader();
if(loader==null)
loader = ClassLoader.getSystemClassLoader(); // assuming you want to load application.properties located in WEB-INF/classes/conf/
String propFile = "conf/application.properties";
java.net.URL url = loader.getResource(propFile);
try{prop.load(url.openStream());}catch(Exception e){System.err.println("Could not load configuration file: " + propFile);}
} //....
// add your methods here. prop is filled with the content of conf/application.properties // load the properties when class is accessed
static {
loadProperties();
}
}This method even works in a standalone java application without any modification. So it is my preferred way.