71

I imported a project from a Git repository and added Maven nature to it in Eclipse. In the resources folder, I added a configuration file called myconf.properties. Now, whenever I try to open this file from my Java code, I get FileNotFoundException. The file is also present in the target/classes folder generated after maven compiles the project.

Can anyone tell me what can be the problem? My Java code that tries to load this file is:

props.load(new FileInputStream("myconf.properties"));

where props is a Properties object.

Can anyone give me some hints on how to solve this issue?

Bilesh Ganguly
  • 3,792
  • 3
  • 36
  • 58
artaxerxe
  • 6,281
  • 21
  • 68
  • 106

7 Answers7

146

If the file is placed under target/classes after compiling, then it is already in a directory that is part of the build path. The directory src/main/resources is the Maven default directory for such resources, and it is automatically placed to the build path by the Eclipse Maven plugin (M2E). So, there is no need to move your properties file.

The other topic is, how to retrieve such resources. Resources in the build path are automatically in the class path of the running Java program. Considering this, you should always load such resources with a class loader. Example code:

String resourceName = "myconf.properties"; // could also be a constant
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
try(InputStream resourceStream = loader.getResourceAsStream(resourceName)) {
    props.load(resourceStream);
}
// use props here ...
Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
  • If you are unfortunate enough to be stuck on Java 6 or below, this code will give you the message "Resource specification not allowed here for source level below 1.7". – k-den Jul 21 '15 at 19:27
  • 3
    @k-den I used the [try-with-resources statement](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) which - you are right - is feature from Java 7 (and later). It can - however - be replaced with a typical try-finally block that works in older Java versions, too. – Seelenvirtuose Jul 22 '15 at 06:00
  • Is the directory location the same for JavaServer pages? – Martin Erlic May 23 '16 at 13:51
  • props.load(new FileInputStream("src/main/resources/myconf.properties")); – Maninder Oct 01 '21 at 17:56
  • @Maninder What? – Seelenvirtuose Oct 04 '21 at 13:32
17

I think you need to put it under src/main/resources and load it as follows:

props.load(new FileInputStream("src/main/resources/myconf.properties"));

The way you are trying to load it will first check in base folder of your project. If it is in target/classes and you want to load it from there do the following:

props.load(new FileInputStream("target/classes/myconf.properties"));
Bilesh Ganguly
  • 3,792
  • 3
  • 36
  • 58
dev2d
  • 4,245
  • 3
  • 31
  • 54
  • 5
    That will not work. As application get's compiled those patches no longer exist. To get resources from classpath you need to use classloader. You need to use something like ResourceBundle.getBundle("myconf.properties") – Ben Apr 23 '18 at 22:00
9

If it is simple application then getSystemResourceAsStream can also be used.

try (InputStream inputStream = ClassLoader.getSystemResourceAsStream("config.properties"))..
rns
  • 1,047
  • 10
  • 25
  • 5
    What do you mean by "simple application" and what are consequences of using your solution in "complex applications"? – user1053510 Nov 15 '18 at 08:01
5

Right click the Resources folder and select Build Path > Add to Build Path

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Only problem would be different remote environments. Read my last comment here - http://stackoverflow.com/a/24795610/1644290 – Soman Dubey Mar 06 '16 at 08:18
4

Using ClassLoader.getSystemClassLoader()

Sample code :

Properties prop = new Properties();
InputStream input = null;
try {
    input = ClassLoader.getSystemClassLoader().getResourceAsStream("conf.properties");
    prop.load(input);

} catch (IOException io) {
    io.printStackTrace();
}
Deep Nirmal
  • 1,141
  • 1
  • 15
  • 14
0

I believe running from Eclipse, if you're using "myconf.properties" as the relative path, You file structure should look somehting like this

ProjectRoot
         src
         bin
         myconf.properties

Eclipse will look for the the file in the project root dir if no other dirs are specified in the file path

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
0

I use something like this to load properties file.

        final ResourceBundle bundle = ResourceBundle
                .getBundle("properties/errormessages");

        for (final Enumeration<String> keys = bundle.getKeys(); keys
                .hasMoreElements();) {
            final String key = keys.nextElement();
            final String value = bundle.getString(key);
            prop.put(key, value);
        }
Karthik Prasad
  • 9,662
  • 10
  • 64
  • 112