Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load properties file in JAR?

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.

like image 271
Andy Avatar asked May 12 '10 00:05

Andy


People also ask

How do I load a properties file?

The Properties file can be used in Java to externalize the configuration and to store the key-value pairs. The Properties. load() method of Properties class is convenient to load . properties file in the form of key-value pairs.

Does jar include properties file?

When you build the JAR file, just include it together with your class files. You can use the method getResourceAsStream() in class Class or ClassLoader to read your properties file inside the JAR file.


2 Answers

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"));   } } 
like image 77
mdma Avatar answered Oct 06 '22 09:10

mdma


For the record, this is documented in How do I add resources to my JAR? (illustrated for unit tests but the same applies for a "regular" resource):

To add resources to the classpath for your unit tests, you follow the same pattern as you do for adding resources to the JAR except the directory you place resources in is ${basedir}/src/test/resources. At this point you would have a project directory structure that would look like the following:

my-app |-- pom.xml `-- src     |-- main     |   |-- java     |   |   `-- com     |   |       `-- mycompany     |   |           `-- app     |   |               `-- App.java     |   `-- resources     |       `-- META-INF     |           |-- application.properties     `-- test         |-- java         |   `-- com         |       `-- mycompany         |           `-- app         |               `-- AppTest.java         `-- resources             `-- test.properties 

In a unit test you could use a simple snippet of code like the following to access the resource required for testing:

...  // Retrieve resource InputStream is = getClass().getResourceAsStream("/test.properties" );  // Do something with the resource  ... 
like image 36
Pascal Thivent Avatar answered Oct 06 '22 08:10

Pascal Thivent