2

To read a properties file in JSF2.0 with Glassfishv3 webserver, which is located at root directory of my web application, I am using below code-

    ServletContext ctx = (ServletContext) FacesContext
            .getCurrentInstance().getExternalContext().getContext();
    String deploymentDirectoryPath = ctx.getRealPath("/");
    Properties prop = new Properties();
    prop.load(new FileInputStream(deploymentDirectoryPath
            + File.separator + "portal-config.properties"));

Below is the screenshot of web portal-

enter image description here

While running the portal I am getting FileNotFound Error, since the file is not present in glassfish domain.

Is there any way to read properties file which can work in both the situations, at development stage and in war file also?

ravi
  • 6,140
  • 18
  • 77
  • 154

1 Answers1

9

You should never use java.io.File to refer web resources. It knows nothing about the context it is sitting in. You should also never use ServletContext#getRealPath() as it may return null when the server is configured to expand WAR file in memory instead of on disk, which is beyond your control in 3rd party hosts.

Just use ExternalContext#getResourceAsStream() to get the web resource directly in flavor of an InputStream. It takes a path relative to the webcontent root.

ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
properties.load(ec.getResourceAsStream("/portal-config.properties"));

See also:


Update it does not seem to be a web resource at all. You should move the file into the "WebContent" folder as shown in the screenshot. Or, better, the /WEB-INF folder so that nobody can access it by URL.

properties.load(ec.getResourceAsStream("/WEB-INF/portal-config.properties"));

An alternative would be to put it in the classpath, the "Java source" folder as shown in the screenshot. You don't need to put it in a package, that's optional. Assuming that you didn't put it in a package, then do so:

ClassLoader cl = Thread.currentThread().getContextClassLoader();
properties.load(cl.getResourceAsStream("portal-config.properties"));

(note that the path may not start with a slash!)

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Getting `java.lang.NullPointerException` with `ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); Properties prop = new Properties(); prop.load(ec.getResourceAsStream(File.separator+ "grinder-config.properties"));` Can you check the code please? – ravi Apr 12 '13 at 16:49
  • Please take a step back. What exactly is `null`? By the way, please don't use `File.separator`. I have nowhere mentioned it in the answer. Classpath/resource paths are not disk file system paths. Using Windows-specific disk file system path separator \ would break it. – BalusC Apr 12 '13 at 16:53
  • The line `prop.load(ec.getResourceAsStream("/portal-config.properties"));` is throwing `java.lang.NullPointerException`. Do you want me to do something for cross checking? – ravi Apr 12 '13 at 17:55
  • You're not specific enough. It look like as if you have no idea why exactly `NullPointerException` is been thrown. You keep telling that you got a `NullPointerException` instead of telling what instance exactly is `null` (which in turn would logically cause NPE when being accessed/invoked). A NPE will be thrown when the code attempts to access/invoke a `null` object. In that line there could be three instances which are `null`: `prop`, `ec` and the returned `InputStream`. So, once again, what exactly is `null`? – BalusC Apr 12 '13 at 17:59
  • Apologize for the inconvenience. Returned `InputStream` is null in my case. FYI, I am using Glassfish v3 server. In my eclipse project the file `portal-config.properties` exists inside root dir which is `Portal` returning by `FacesContext.getCurrentInstance().getExternalContext()`. What else I am missing? – ravi Apr 12 '13 at 21:01
  • 2
    Root dir? The screenshot shows that it's inside `WebContent`, or am I blind? My answer expected it to be in web folder. Anyway .. Placing it in the project root is just strange. Either put it in web folder, or in source folder. If you place it in source folder ("Java resources") then you can get it from the classpath by among others `Thread.currentThread().getContextClassLoader().getResourceAsStream("portal-config.properties")` (without the slash!) – BalusC Apr 12 '13 at 21:01
  • @BalusC Maybe it's a dumb question but can this be made in a more static way ? I mean if the properties file is gonna be in the same package regardless of which thread is currently using the bean, I find it a bit odd that we have to go through the current thread. (When trying to read a property file from a managedBean). – Ced Sep 27 '15 at 02:38
  • @BalusC what if i would want to write to that file instead of read? i can't get a OutputStream - what to do? Im circling here.. ^^ – Gewure Sep 04 '17 at 13:41
  • @Gewure Follow last "See also" link. – BalusC Sep 04 '17 at 15:04