How do I get a resource that is in the same package as the class that will use it?

4

I've created a Java project with the following structure:

src
 |-br.foo.settings
 |     |- settings.json
 |     |- Settings.java
 |   
 |- ... outros pacotes ...

As I'm accustomed to the JSON file format, I thought I'd create one to set the main application settings (as you can see, it's in the br.foo.settings package).

To illustrate, there is some information about the repository, dependencies, directories where I should save application data, etc. An example structure:

{
    locais: [
        {"padrao":"stackoverflow"},
        {"usuario":"2"},
        ...
    ],
    ...
}

The class Settings is responsible for getting a configuration value based on key . For example, suppose I want the key "default" (in "places") I would call a method that returns stackoverflow.

The problem ...

All this works normally when I test and execute the project in the IDE, but when I give build and try to execute the created .jar, a NullPointerException exception is thrown because it can not find the settings.json .

Here's my first question:

Is this file not bundled with .jar?

Well, continuing, as the file is in the same package as the Settings class, I'm using the following code to get the file:

// Settings.java 
File arquivoDeConfiguracao = FileUtils.toFile(getClass().getResource("settings.json"));

The use of " getClass().getResource(...) " has always worked for me, but in this case it's frustrating me!

Is there any way to package this .json file with .jar? I'm pretty sure the problem is this, because the method I'm using to get the file is catching a null object, but the funny thing is that when I run it through the IDE it works OK.

My second question is:

I'm using Maven and I noticed that it has a directory called "resources". If I move that JSON file there, will it be bundled with .jar?

I accept suggestions for alternatives, for the time being I'm considering reading the JSON file the best. For example, is there any other way to write a file with data that should be used by the application other than creating enum ?

    
asked by anonymous 18.04.2015 / 04:05

1 answer

2

I was able to solve the problems, but I made some changes to the project structure.

src
 |- java
 |    |
 |    |- br.foo.settings
 |           |- Settings.java
 |- resources
       |- settings.json

I'm getting the file through InputStream as follows:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream inputstr = classLoader.getResourceAsStream("settings.json"); // YEAAH!
inputstr.close();

If the above form does not work, some searches on Google have led me to this library which performs a more accurate search of the file.

To convert this stream to a String, I followed this response (sensational) in StackOverflow making use of an object Scanner .

import java.io.InputStream;
import java.util.Scanner;

public class Foo {
    public static void main(String... args) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream inputstr = classLoader.getResourceAsStream("settings.json");

        String json = new Scanner(inputstr, "UTF8").useDelimiter("\A").next();
        System.out.println(json); // YEAHH :D
        inputstr.close();
    }
}
    
19.04.2015 / 01:37