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.

39 comments:

  1. 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?

    ReplyDelete
  2. 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

    ReplyDelete
  3. 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.

    ReplyDelete
  4. hello , ı am Faruk

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

    best regards

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

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

    ReplyDelete
  7. This comment has been removed by the author.

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

    ReplyDelete
  9. 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

    ReplyDelete
  10. 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");

    ReplyDelete
  11. 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,

    ReplyDelete
  12. 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

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

    ReplyDelete
  14. This info was very helpful to me - thanks!

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. 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

    ReplyDelete
  17. 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

    ReplyDelete
  18. 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.

    ReplyDelete
  19. 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.

    ReplyDelete
  20. 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;
    }

    ReplyDelete
  21. 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.

    ReplyDelete
  22. 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?

    ReplyDelete
  23. 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?

    ReplyDelete
  24. Lavanya,

    What does the entire exception stacktrace look like?

    ReplyDelete
  25. 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

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

    ReplyDelete
  27. 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());

    ReplyDelete
  28. 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.

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

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

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

    ReplyDelete
  32. {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.

    ReplyDelete
  33. 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!

    ReplyDelete
  34. 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)

    ReplyDelete

  35. 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

    ReplyDelete
  36. 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

    ReplyDelete
  37. Easy, simple and Understandable....Thanks

    ReplyDelete
  38. It is also important to close the file which is opened in the finally block

    ReplyDelete
  39. That's right. Be sure to close the InputStream when you are done using it.

    ReplyDelete