HedonicHedgehog
HedonicHedgehog

Reputation: 592

How do I update a properties file dynamically?

My application is a batch process that pulls environment variables from an application.properties file. The password that I use must be updated every few months. I would like to automate the password update process and save the updated password in the properties file so it can be used in future runs, but any updates I try to make are not propagated to the application.config file.

When I run in Intellij, there are no errors, but the file is not updated. When I run the application as a jar, it gives:

java.io.FileNotFoundException: file:{localpath}\application.jar!\BOOT-INF\classes!\application.properties (The filename, directory name, or volume label syntax is incorrect)

How do I dynamically update the application.properties file within the jar or do I need to create a new properties file outside of the jar when the application first runs??

EXAMPLE CODE SNIPPETS BELOW:

properties.config:

username=user
password=password123

Application.java:

    //get properties
    prop = new Properties();
    InputStream input = null;
    try {
        input = new FileInputStream(f);
        // load a properties file
        prop.load(input);
    } catch (IOException ex) {
        logger.error("Error reading application.properties", ex);
        ex.printStackTrace();
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //update properties
    prop.setProperty("TESTSTRING", "testvalue");

    //write to properties file
    OutputStream os = null;
    try{
        File f = new File(Application.class.getClassLoader().getResource("application.properties").getFile());
        os = new FileOutputStream(f);
        prop.store(os, comments);
    }catch(IOException ex){
        logger.error("Error updating application.properties", ex);
        ex.printStackTrace();
    } finally {
        if(os != null){
            try{
                os.close();
            } catch (IOException e){
                e.printStackTrace();
            }
        }

Upvotes: 2

Views: 5677

Answers (1)

davidxxx
davidxxx

Reputation: 131526

Properties of an application that may change according to the running environment should never be packaged inside the packaged component.
It should be not hard coupled to the component and it should also be modifiable if required without modifying the packaged component.
Besides, properties may contain confidential information (as in your case : username and password).
So it should be preferably stored directly on the target environment.

For example, one of the cloud native application principles from Heroku/twelve factors (that are also good practices in general) is "storing the configuration in the environment".

So updating the properties file inside the packaged component has to be absolutely avoided for the same reasons.
Besides doing it makes the state application more hard to reproduce if an errors occurs.


In your case, simply fill username and password properties in a specific properties file according to the target environment and store this file on the environment.

Then you have just to run the application by specifying this properties file.
For example for windows :

java -jar yourApp-1.0.jar --spring.config.location=file:///D:/application-target-env.properties

Here is the reference documentation about it : 24.2 Accessing command line properties

Upvotes: 1

Related Questions