Thursday, January 04, 2007

How to read a properties file in a web application

The code to do this is pretty simple. But going by the number of people who keep asking this question, i thought i would post the code over here. Let's consider that you have a war file named SampleApp.war which has a properties file named myApp.properties at it's root :



SampleApp.war
|
|-------- myApp.properties
|
|-------- WEB-INF
|
|---- classes
|
|----- org
|------ myApp
|------- MyPropertiesReader.class





Let's assume that you want to read the property named "abc" present in the properties file:

----------------
myApp.properties:
----------------

abc=some value
xyz=some other value


Let's consider that the class org.myApp.MyPropertiesReader present in your application wants to read the property. Here's the code for the same:



package org.myapp;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* Simple class meant to read a properties file
*
* @author Jaikiran Pai
*
*/
public class MyPropertiesReader {

/**
* Default Constructor
*
*/
public MyPropertiesReader() {

}

/**
* Some Method
*
* @throws IOException
*
*/
public void doSomeOperation() throws IOException {
// Get the inputStream
InputStream inputStream = this.getClass().getClassLoader()
.getResourceAsStream("myApp.properties");

Properties properties = new Properties();

System.out.println("InputStream is: " + inputStream);

// load the inputStream using the Properties
properties.load(inputStream);
// get the value of the property
String propValue = properties.getProperty("abc");

System.out.println("Property value is: " + propValue);
}

}




Pretty straight-forward. Now suppose the properties file is not at the root of the application, but inside a folder (let's name it config) in the web application, something like:




SampleApp.war
|
|-------- config
| |------- myApp.properties
|
|
|-------- WEB-INF
|
|---- classes
|
|----- org
|------ myApp
|------- MyPropertiesReader.class




There will just be one line change in the above code:




public void doSomeOperation() throws IOException {
//Get the inputStream-->This time we have specified the folder name too.
InputStream inputStream = this.getClass().getClassLoader()
.getResourceAsStream("config/myApp.properties");

Properties properties = new Properties();

System.out.println("InputStream is: " + inputStream);

//load the inputStream using the Properties
properties.load(inputStream);
//get the value of the property
String propValue = properties.getProperty("abc");

System.out.println("Property value is: " + propValue);
}



That's all that is required to get it working.

37 comments:

Anonymous said...

How is it that the getResourceAsStream knows where to look to find the properties file? Why does it know to look starting from the top of the WAR?

Jaikiran said...

The getResourceAsStream looks for a resource in the classloaders. As you can see in the code, we first get access to the classloader which has loaded your application (.war) and then invoke the getResourceAsStream method which starts searching this classloader for the resource.

I have tried to put this answer in simple terms. The javadocs have a very good explanation for the same:

getResourceAsStream

getResource

Rashmi Tambe said...

Refer to following article on apache site -

http://tomcat.apache.org/tomcat-4.1-doc/class-loader-howto.html

It talks about class path and class loading within war files.

Anonymous said...

hello , ı am Faruk

I am dog tired while tring to do this problem,
thanks about your solution

best regards

Anonymous said...

Just what I was looking for. Spent the better part of my lunch break trying to figure this out :-(
Thanks, man!

abhishek said...

I am new for java development and I find what i was searching for. Thanks a lot to My Wiki

Rajeev said...
This comment has been removed by the author.
Raj said...

I am using netbeans 6 and deploying my app to sun webserver 7, due to some reason it is not working, any suggestions pleassssss

Anonymous said...

Ok, that's great but how do I read the properties file from java when I'd like to put the properties file into the Apllication Server properties folder
eg. AppServer/properties

dracik said...

For me, using eclipse and tomcat6.0.13, it was necessary to put my connection.xml file into /WEB-INF/classes directory. Then I used the first way to create InputStream:

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("connection.xml");

Sagar R said...

Whats difference between ResourceBundle class which loads .properties file and the above InputStream approach ? Which one is better ?

I think, when we use ResourceBundle , we can't load a file from directory which is outside the CLASSPATH , Am I right ? Pl reply !

Thanks,

Roses said...

In the above example you mentioned are you trying read a file which is not part of the war file but it is from a application module.

I am here talking about ear deployment

Then how to read a resource

Anonymous said...

If I want the web service to ask Tomcat on which port and url it is running, which resource should I use?

Anonymous said...

This info was very helpful to me - thanks!

indiroma said...
This comment has been removed by the author.
Anonymous said...

Thank you, I had to change an application that someone else had written and had never used a properties file before (or maybe I just forgot). After banging my head against the wall decided to search and found your info. thanks very much. Ann

Deepak said...

You can even use it without explicitly calling the getClassLoader()

InputStream is = getClass().getResourceAsStream("/init.properties");

Make sure you take note of the "/" at the begining. The "/init.properties" needs to be in the WEB-INF/classes folder

Nagaraju said...

Hi jaikiran My Name is nagaraju. i am also a java/j2ee developer. i would like to create one blog like u, can u tell me how did u create u r blog. plz.............I am so impressed for u r blog.

Jaikiran said...

Hi Nagaraju,

blogspot.com allows you to create blogs of your own. There are other services like wordpress.com too which allow you to create blogs for free.

On the top right corner of my blogspot, you will find a "Create Blog" link. Just click on that link and follow the instructions.

Yogi said...

How about is the method is static method that returns property value ? In that you can not instantiate some thing like this.class.

For example in my case I have utility method,

public static String getPropertyValue(String name){
Properties properties = new Properties();

try {
//This is not working properties.load(new FileInputStream("/webapps/DayParser/enviornment.properties"));
return properties.getProperty(name);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

Anonymous said...

I found this worked only when I put the properties file in the "WEB-INF\classes" folder.

It did not work when it was in the WEB-INF directory.

I am using NetBeans, JDK 6 and a web service application on Glassfish.

Anonymous said...

I am using JDK 1.5 and Tomcat 5.25

I call from a jsp
.
.
import="org.myApp.MyPropertiesReader"
.
.
.
.

MyPropertiesReader mp = new MyPropertiesReader();
mp.doSomeOperation();


This is the console with the exception

INFO: Server startup in 906 ms
InputStream is: null
03/12/2009 13:27:12 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet jsp lanzó excepción
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:365)
at java.util.Properties.load(Properties.java:293)
at org.myApp.MyPropertiesReader.doSomeOperation(MyPropertiesReader.java:39)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:55)

========================

and I also from a servlet


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
MyPropertiesReader mp = new MyPropertiesReader();
mp.doSomeOperation();
}

This is the console with the exception

INFO: Server startup in 907 ms
InputStream is: null
03/12/2009 13:25:21 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() para servlet Prueba lanzó excepción
java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:365)
at java.util.Properties.load(Properties.java:293)
at org.myApp.MyPropertiesReader.doSomeOperation(MyPropertiesReader.java:39)
at org.servlet.Prueba.doGet(Prueba.java:45)

======

Please
What I am doing wrong?

Lavanya said...

I am trying to follow what you're doing here, but I get a null pointer exception from the load function. I am trying to do this in a jsp.

any thoughts on this?

Jaikiran said...

Lavanya,

What does the entire exception stacktrace look like?

Ajay Karthik said...

Wasted a good amount of time before finding your blog... thanks for the info and people please go through this link http://tomcat.apache.org/tomcat-4.1-doc/class-loader-howto.html to understand the class loading in tomcat

Ann said...

You saved me much headache. Plus I also learned something. Thanks
Ann

Gopi said...

If you are want to load the properties file in a static way, use URL instead of 'InputStream'. Please find the code snippet below.

URL url = Class_Name.class.getClassLoader().getResource("WEB-INF/property_file_name.properties");
properties = new Properties();
properties.load(url.openStream());

Toolman said...

For portability in webapps, you cant rely on it finding items in the root context. See this stackoverflow post:

http://stackoverflow.com/questions/2308188/getresourceasstream-vs-fileinputstream

I recommend you consider using servletContext.getResource where possible, as it is guaranteed to be looking relative to your apps context.

mathieu said...

Thanks for the clear explanation. And also thanks to dracik for the extra info about eclipse and tomcat: exactly what I needed!

Anonymous said...

The resource should be kept in WEB-INF\classes, NOT inside WEB-INF.

Anonymous said...

This method is great, but what my 'doSomeOperation()' method is static. Is there a way to cater for this?

Jaikiran said...

{quote}
This method is great, but what my 'doSomeOperation()' method is static. Is there a way to cater for this?
{quote}

It's just a matter of getting to the right classloader. So instead of this.getClass().getClassLoader(), if the method in which you are using this is static, just use MyPropertiesReader.class.getClassLoader() or a similar technique.

Rafael Cintra said...

Man, you are the God, this is so simple but I took over 2 hours to get this code to implement my app. A special thanks from Brazil!

thierry said...

I try to use your java class to read a property file but each time I used it, i've got a java.lang.NullPointerException. Don't understand what i'm doing wrong

Here's the error message :
INFO: wsimport successful
INFO: InputStream is: null
GRAVE: java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at fr.inra.ga.helloworld.MyPropertiesReader.getProperty(MyPropertiesReader.java:42)
at fr.inra.ga.helloworld.HelloWorld.hello(HelloWorld.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.glassfish.webservices.InstanceResolverImpl$1.invoke(InstanceResolverImpl.java:143)
at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:149)
at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:94)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:116)
at org.glassfish.webservices.MonitoringPipe.process(MonitoringPipe.java:142)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:116)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.processRequest(CommonServerSecurityPipe.java:212)
at com.sun.enterprise.security.webservices.CommonServerSecurityPipe.process(CommonServerSecurityPipe.java:144)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:119)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:386)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:640)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:263)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:163)
at org.glassfish.webservices.JAXWSServlet.doPost(JAXWSServlet.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)

thierry said...


at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:662)



PS : the method doSomeOperation became method getProperty in my class

HIMA said...

Hi, i'm working on selenium tool. I've some problem reading data from a properties file, getting null pointer exception. This is happening when i write some data through automation and read the same data from the file. Please help

I'm using Eclipse IDE and java code in selenium webdriver

Anonymous said...

Easy, simple and Understandable....Thanks