Load properties file in JAR?

Andy picture Andy · May 12, 2010 · Viewed 116.1k times · Source

I'm having trouble when one of the jars that my web app depends on tries to load a properties file from within the jar. Here is the code in the jar.

static
{
    Properties props = new Properties();
    try 
    {
        props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
    } catch (IOException e) 
    {
        e.printStackTrace();
    }
    someProperty = props.getProperty("someKey");
}

The properties file is in my "src/main/resources" directory of the Maven project. When I run this code from my junit test in Eclipse, it executes just fine. When the project is built with Maven into a jar, and included as a dependency in my web app, it fails to locate the properties file. I know that the properties file is at the base directory of the depended on jar, I don't know how to fix this.

Answer

mdma picture mdma · May 12, 2010

The problem is that you are using getSystemResourceAsStream. Use simply getResourceAsStream. System resources load from the system classloader, which is almost certainly not the class loader that your jar is loaded into when run as a webapp.

It works in Eclipse because when launching an application, the system classloader is configured with your jar as part of its classpath. (E.g. java -jar my.jar will load my.jar in the system class loader.) This is not the case with web applications - application servers use complex class loading to isolate webapplications from each other and from the internals of the application server. For example, see the tomcat classloader how-to, and the diagram of the classloader hierarchy used.

EDIT: Normally, you would call getClass().getResourceAsStream() to retrieve a resource in the classpath, but as you are fetching the resource in a static initializer, you will need to explicitly name a class that is in the classloader you want to load from. The simplest approach is to use the class containing the static initializer, e.g.

[public] class MyClass {
  static
  {
    ...
    props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
  }
}