0

I am in the process of working on a discord bot for a class, and I am having trouble with my token and github. I am trying to set it up so that the token is read from a config.properties file that can be updated with a bot token. However, my professor said that I should be setting it up so that I have a binary executable that can be downloaded as a release from the GitHub repo and users should simply provide their own config.properties file in the designated folder they are instructed. However, I don't understand/know how I can compile an executable Java program that is dependent on the value of the file read at runtime without recompiling after every time that the config.properties file is changed. Right now, I have the application set up as a JAR file, and I don't know how else to make the program downloadable to a user without sharing it as a JAR, but that means it needs to be recompiled after each change to the config.properties file. I'm at a loss and not sure I totally understand JAR files.

EDIT: Here's the code I am using to read in my config properties.

public class ReadConfig {
    String token = "";
    InputStream inputStream = null;
    // won't take string with file
    String file = "config.properties";
    Properties prop = new Properties();

    public String getToken() throws IOException{
        try{
            inputStream = getClass().getClassLoader().getResourceAsStream(file);
            prop.load(inputStream);
            token = prop.getProperty("token");
           // System.out.println("Token: " + token);
        } catch (Exception e){
            System.out.println("Exception: " + e);
        } finally {
            inputStream.close();
        }
        return token;
    }
}

My config.properties file is structured below:

# Config properties for the bot
token=TOKENHERE

I've been using the Gradle ShadowJar plugin in Intellij to create the executable JAR. I've tried moving the JAR to the same folder as the config.properties file, and updating the config.properties file between runs but if I update with an invalid token, it will still work until I completely rebuild and compile the JAR over again.

  • You do not need to run code to compile it. The code simply takes the file the path and compiles the actions to take, it does not care what the data in an external file is. An example config should be supplied alongside the compiled jar (Not inside it), and the jar should read from that config when placed in the same folder. No token should be stored in the code itself. – sorifiend Nov 09 '21 at 03:31
  • 1
    Here is one example of how you can read from a file: [Reading a plain text file in Java](https://stackoverflow.com/questions/4716503/reading-a-plain-text-file-in-java) There are other ways to create/manage config files with different file formats (JSON etc), but this will get you started. – sorifiend Nov 09 '21 at 03:35
  • 1
    It might help if you add the code which uses the config.properties file to your question. – tgdavies Nov 09 '21 at 03:47
  • @sorifiend thanks for your response. I think I'm a little confused, is there anything in the build settings that I have to specify in order to get it to read from the config file? I am using Gradle with the ShadowJar plugin, and I used the Properties class to read in from a config.properties file in my resources folder. however, when I update the token on that .properties file between runs, nothing changes - even if the token is invalid - unless I completely recompile. – bashful_creature Nov 09 '21 at 04:02
  • Your updated code shows that you are loading from an internal resource file that is compiled into your jar, here `getClass().getClassLoader().getResourceAsStream(file)`. Instead, you need to load from an external config file, for example, this will create a file input stream to a file named "foo.txt" that is located in the same folder as the jar `FileInputStream inputStream = new FileInputStream("foo.txt");` or this would load from an exact location using an absolute path `FileInputStream inputStream = new FileInputStream("C:/yourPath/foo.txt");` – sorifiend Nov 09 '21 at 04:11
  • 1
    @sorifiend thank you so much! I was able to update it to FileInputStream and it is correctly working now. :) – bashful_creature Nov 09 '21 at 04:33

0 Answers0