Why can't my Java Application find my properties file

17,082

Solution 1

Thanks to everyone for helping out, especially dashrb, plus 1 for your code.

I managed to get it working with your help. The final solution to this problem was a slight change of tack.

As I had the need to read and write to the file (probably not clear in my OP) I switched to using Apache.commons.configuration.

That said the pointers in this thread did ensure my other properties files were working without hitch.

Thanks again

Solution 2

Perhaps the FileInputStream isn't able to honor the properties "file" which is inside your jar file. Change your:

this.runController = new Properties();
this.propertiesLocation = this.getClass().getClassLoader().getResource(this.PROPERTIESFILELOCATION);
FileInputStream propsInput = new FileInputStream(this.propertiesLocation.getFile());
this.runController.load(propsInput);

to:

this.runController = new Properties();
this.runController.load(this.getClass().getClassLoader().getResourceAsStream(this.PROPERTIESFILELOCATION));

EDIT: I created a test class, and it shows that when running from the filesystem OR from a JAR file, that "props/main.properties" works but "/props/main.properties" does not:

[rtb@rtblinux props]$ cat org/dashrb/test/main.java 
package org.dashrb.test;
import java.util.Properties;
import java.io.IOException;

public class main
{
    public static void main(String args[])
    {
        main myMain = new main();
        myMain.testProps("props/main.properties");
        myMain.testProps("/props/main.properties");
    }

    public main()
    {
    }

    public void testProps(String p)
    {
        try
        {
            System.out.println("===============================");
            Properties props = new Properties();
            System.out.println("Trying to load properties as " + p);
            props.load(getClass().getClassLoader().getResourceAsStream(p));
            System.out.println("Loaded properties as " + p);
            System.out.println("Property x is: " + props.getProperty("x"));
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
        System.out.println("===============================");
    }
}

[rtb@rtblinux props]$ cat props/main.properties 
x = This is the property value of x

[rtb@rtblinux props]$ java -cp . org.dashrb.test.main
===============================
Trying to load properties as props/main.properties
Loaded properties as props/main.properties
Property x is: This is the property value of x
===============================
===============================
Trying to load properties as /props/main.properties
Exception in thread "main" java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Properties.java:434)
    at java.util.Properties.load0(Properties.java:353)
    at java.util.Properties.load(Properties.java:341)
    at org.dashrb.test.main.testProps(main.java:25)
    at org.dashrb.test.main.main(main.java:11)




[rtb@rtblinux props]$ jar cvf main.jar org props
added manifest
adding: org/(in = 0) (out= 0)(stored 0%)
adding: org/dashrb/(in = 0) (out= 0)(stored 0%)
adding: org/dashrb/test/(in = 0) (out= 0)(stored 0%)
adding: org/dashrb/test/main.class(in = 1218) (out= 679)(deflated 44%)
adding: org/dashrb/test/main.java(in = 594) (out= 287)(deflated 51%)
adding: props/(in = 0) (out= 0)(stored 0%)
adding: props/main.properties(in = 36) (out= 36)(deflated 0%)

[rtb@rtblinux props]$ jar tvf main.jar 
     0 Fri Jan 11 17:29:40 EST 2013 META-INF/
    68 Fri Jan 11 17:29:40 EST 2013 META-INF/MANIFEST.MF
     0 Fri Jan 11 17:26:00 EST 2013 org/
     0 Fri Jan 11 17:26:00 EST 2013 org/dashrb/
     0 Fri Jan 11 17:29:24 EST 2013 org/dashrb/test/
  1218 Fri Jan 11 17:28:52 EST 2013 org/dashrb/test/main.class
   594 Fri Jan 11 17:29:24 EST 2013 org/dashrb/test/main.java
     0 Fri Jan 11 17:26:40 EST 2013 props/
    36 Fri Jan 11 17:26:40 EST 2013 props/main.properties

[rtb@rtblinux props]$ cd /
[rtb@rtblinux /]$ java -cp ~/misc/src/java/props/main.jar org.dashrb.test.main
===============================
Trying to load properties as props/main.properties
Loaded properties as props/main.properties
Property x is: This is the property value of x
===============================
===============================
Trying to load properties as /props/main.properties
Exception in thread "main" java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Properties.java:434)
    at java.util.Properties.load0(Properties.java:353)
    at java.util.Properties.load(Properties.java:341)
    at org.dashrb.test.main.testProps(main.java:25)
    at org.dashrb.test.main.main(main.java:11)

There must be something different in your situation which is preventing your success.

Solution 3

Your question talks about

conf/controller.properties

and your code talks about conf/runController.properties

EDIT: I'm assuming that the conf/*.properties is inside your jar file. If thats the case, then your code should work if the files are named correctly.

Solution 4

If you use getResource to open the properties file, that assumes that the file is in the classpath, so you need to put the properties file in the classpath. The alternatives are to add the conf directory to the classpath, or move the properties file so that it is in the existing classpath.

One thing that might help is to refer to the file location with a starting slash, so there is no doubt that you want to start searching for the file from the root of the classpath. Otherwise the search path is relative to the class your code is making the call from (don't know that this is right; that's how it works with Class.getResource, Classloader.getResource may be different though).

Share:
17,082
nathj07
Author by

nathj07

All round developer, keen to learn and try new things. I love to hike and bike and am happiest when outdoors with my family.

Updated on August 09, 2022

Comments

  • nathj07
    nathj07 almost 2 years

    I have a simple application that reads from and writes to a properties file. It was developed in NetBeans and when run from within Netbeans works just fine. However, now I have built and deployed it the properties file cannot be found.

    Project Structure

    com/company/projectname/controller/controllerclass.java <- this is where the code using the properties file exists
    
    conf/runController.properties <- the properties file, this exists here
    

    In the code I have the following to access the properties file:

    private final String PROPERTIESFILELOCATION = "conf/runController.properties";
    
    public void runController(){
    this.runController = new Properties();
    this.propertiesLocation = this.getClass().getClassLoader().getResource(this.PROPERTIESFILELOCATION);
    FileInputStream propsInput = new FileInputStream(this.propertiesLocation.getFile());
    this.runController.load(propsInput);
    }
    

    (summarized for brevity)

    When I call the jar file from the command line I issue:

    java -classpath /usr/java/projectdirectory/project.jar com.company.projectname.controller.controllerclass arg1
    

    So, I have managed to achieve this before on other projects in just this way but for some reason this is not working.

    I have checked the structure inside the jar file and all is as expected in there.

    Can anyone point out my mistake and help me get this up and running please?

    EDIT- changed the names to match across. They were always consistent in my code

  • dashrb
    dashrb over 11 years
    One would hope that the properties file is inside the jar file. I think Kal has it right--the name isn't the same.
  • Nathan Hughes
    Nathan Hughes over 11 years
    @dashrb: that was a good catch (+1 from me), certainly the name discrepancy doesn't help matters. there may be more than 1 thing wrong, of course.
  • nathj07
    nathj07 over 11 years
    the name discrepancy is just an issue in the example I have posted. I have corrected that now, thanks for spotting it.
  • nathj07
    nathj07 over 11 years
    the properties file is in the jar at conf/runController.properties. The conf directory is at the same level as the com directory within the jar
  • nathj07
    nathj07 over 11 years
    Yeah, its in the jar and the names match.
  • Nathan Hughes
    Nathan Hughes over 11 years
    @nathj07: so conf and com are both at the root level of the jar file? does the jar have a META-INF directory with a MANIFEST.MF in it?
  • nathj07
    nathj07 over 11 years
    sure does Class-Path: lib/bzip2.jar lib/wikixmlj-r43.jar lib/DataAbstractionLaye r.jar lib/log4j-1.2.17.jar lib/mail.jar lib/mysql-connector-java-5.1. 9.jar lib/commons-codec-1.5.jar lib/tika-core-1.0.jar lib/jsoup-1.7.1 .jar lib/commons-codec-1.6.jar lib/commons-logging-1.1.1.jar lib/flue nt-hc-4.2.1.jar lib/httpclient-4.2.1.jar lib/httpclient-cache-4.2.1.j ar lib/httpcore-4.2.1.jar lib/httpmime-4.2.1.jar lib/bliki-core-3.0.1 9.jar lib/bliki-addons-3.0.19.jar lib/bliki-pdf-3.0.19.jar lib/xmlwri ter-2.2.2.jar lib/xmlenc-0.52.jar X-COMMENT: Main-Class will be added automatically by build
  • nathj07
    nathj07 over 11 years
    I tried that I either get Null pointer for conf/runController.properties or for /conf/runController.properties I get null pointer on java.util.Properties$LineReader.readLine This is alla liltte baffling as I've never had such issues before
  • dashrb
    dashrb over 11 years
    I know you've looked at the names already. can you verify the capitalization? if you're on windows, filenames on the disk aren't case sensitive but (I believe) the contents of jar files are.
  • nathj07
    nathj07 over 11 years
    For sure. The capitalization is correct and consistent. The file is called runController.properties and is referred to as such.
  • dashrb
    dashrb over 11 years
    I have created a small program which loads the properties similarly, and it works, without the leading /. I'll edit my answer above.... There must be something strange in your situation. Work your code closer to my code until you find it.
  • nathj07
    nathj07 over 11 years
    Thanks for the sample code. I have worked my code closer to that and I get file not found now. It seems that some piece is missing that allows my app to find that file.
  • dashrb
    dashrb over 11 years
    If you are able to run my code as is, and it works, then it's just a matter of stepping little by little from my code to yours. Good luck!