mike01010
mike01010

Reputation: 6088

Java/Gradle reading external config files

My project structure looks like below. I do not want to include the config file as a resource, but instead read it at runtime so that we can simply change settings without having to recompile and deploy. my problem are two things

  1. reading the file just isn't working despite various ways i have tried (see current implementation below i am trying)
  2. When using gradle, do i needto tell it how to build/or deploy the file and where? I think that may be part of the problem..that the config file is not getting deployed when doing a gradle build or trying to debug in Eclipse.

My project structure:

myproj\
        \src
            \main
                \config
                    \com\my_app1\
                                config.dev.properties
                                config.qa.properties
                \java
                    \com\myapp1\
                                \model\
                                \service\
                                \util\
                                    Config.java
            \test              

Config.java:

public Config(){
        try {
            String configPath = "/config.dev.properties"; //TODO: pass env in as parameter
            System.out.println(configPath);
            final File configFile = new File(configPath);
            FileInputStream input = new FileInputStream(configFile);

            Properties prop = new Properties()
            prop.load(input);
            String prop1 = prop.getProperty("PROP1");
            System.out.println(prop1);
        } catch (IOException ex) {
            ex.printStackTrace();
        } 
    }   

Upvotes: 13

Views: 13570

Answers (5)

fanshaoer
fanshaoer

Reputation: 99

I am not familiar with gradle,so I can only give some advices about your question 1.I think you can give a full path of you property file as a parameter of FileInputStream,then load it using prop.load.

FileInputStream input = new FileInputStream("src/main/.../config.dev.properties");

Properties prop = new Properties()
prop.load(input);
// ....your code

Upvotes: 1

mike01010
mike01010

Reputation: 6088

The solution for me to be able to read an external (non-resource) file was to create my config folder at the root of the application.

myproj/
      /configs

Doing this allowed me to read the configs by using 'config/config.dev.properies'

Upvotes: 1

lance-java
lance-java

Reputation: 28099

Your question is slightly vague but I get the feeling that you want the config files(s) to live "outside" of the jars.

I suggest you take a look at the application plugin. This will create a zip of your application and will also generate a start script to start it. I think you'll need to:

  1. Customise the distZip task to add an extra folder for the config files
  2. Customise the startScripts task to add the extra folder to the classpath of the start script

Upvotes: 1

VHS
VHS

Reputation: 10194

Ans 1.

reading the file just isn't working despite various ways i have tried (see current implementation below i am trying)

With the location of your config file you have depicted,

Change

String configPath = "/config.dev.properties";

to

String configPath = "src\main\config\com\my_app1\config.dev.properties";

However read the second answer first.

Ans 2:

When using gradle, do i needto tell it how to build/or deploy the file and where? I think that may be part of the problem..that the config file is not getting deployed when doing a gradle build or trying to debug in Eclipse.

You have two choices:

  1. Rename your config directory to resources. Gradle automatically builds the resources under "src/main/resources" directory.
  2. Let Gradle know the additional directory to be considered as resources.

    sourceSets {
        main {
            resources {
                srcDirs = ["src\main\config\com\my_app1"]
                includes = ["**/*.properties"]
            }
        }
     }
    

Upvotes: 5

Flood2d
Flood2d

Reputation: 1358

reading the file just isn't working despite various ways i have tried (see current implementation below i am trying)

You need to clarify this statement. Are you trying to load properties from an existing file? Because the code you posted that load the Properties object is correct. So probably the error is in the file path.

Anyway, I'm just guessing what you are trying to do. You need to clarify your question. Is your application an executable jar like the example below? Are trying to load an external file that is outside the jar (In this case gradle can't help you)?

If you build a simple application like this as an executable jar

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class Main {
    public static void main(String[]args) {
        File configFile = new File("test.properties");
        System.out.println("Reading config from = " + configFile.getAbsolutePath());

        FileInputStream fis = null;
        Properties properties = new Properties();

        try {
            fis = new FileInputStream(configFile);
            properties.load(fis);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            if(fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {}
            }
        }

        System.out.println("user = " + properties.getProperty("user"));
    }
}

When you run the jar, the application will try to load properties from a file called test.properties that is located in the application working directory.

So if you have test.properties that looks like this

user=Flood2d

The output will be

Reading config from = C:\test.properties
user = Flood2d

And that's because the jar file and test.properties file is located in C:\ and I'm running it from there.

Some java applications load configuration from locations like %appdata% on Windows or /Library/Application on MacOS. This solution is used when an application has a configuration that can change (it can be changed by manually editing the file or by the application itself) so there's no need to recompile the application with the new configs.

Let me know if I have misunderstood something, so we can figure out what you are trying to ask us.

Upvotes: 4

Related Questions