2
\$\begingroup\$

I wanted an opinion about an idea I had regarding the use of config.properties, static classes and the use of reflection.

I have to load some preferences at application startup, for that I will be using config.properties. Certain properties within config.properties will be changed during various points in the program. So, instead of opening, searching for the property, updating and closing properties.config - I was thinking I could use a static class to read and write values, use reflection to write values back and forth between static class and properties.config file during application startup and close.

Is there a better approach I should be considering? Should I be avoiding static class?

Here is simplified code

//Class with static variables, the values get used and updated at 
//various points within the program. For example prop1 gets updated and used
//at a different points in the program. Also, they are active at
//different  points in the program than prop1 and prop2.
//values need to be saved for application startup.

public class StaticProp {
    public static String prop1 = "a";
    public static String prop2 = "b";
    public static String prop3 = "c";
}

During application close, using Reflection - write values to properties.config

    private void writeConfigProp() {
    Properties prop = new Properties();
    OutputStream outputStream = null;
    try {
        outputStream = new FileOutputStream("resources/config.properties");
        Field[] fields = StaticProp.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                prop.setProperty(field.getName(), Utility.tryParseVal(field.get(null)));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        prop.store(outputStream, "Config for UI");
    } catch (IOException io) {
        io.printStackTrace();
    } finally {
        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

During application startup, using Reflection - read properties.config to static class.

    /**
 * Read Config Properties
 */
private void readConfigProp() {
    Properties prop = new Properties();
    InputStream inputStream = null;

    try {
        inputStream = new FileInputStream("resources/config.properties");
        prop.load(inputStream);

        Field[] fields = PropConfig.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                try {
                    field.set(null, prop.getProperty(field.getName()));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ I have rolled back the last edit. Please see What to do when someone answers. \$\endgroup\$
    – h.j.k.
    Commented May 11, 2015 at 4:05
  • \$\begingroup\$ Follow-up: Please post your new approach as a new question, so that it probably stands a better chance of getting a fuller review as well. Thanks! Welcome to CR BTW! \$\endgroup\$
    – h.j.k.
    Commented May 11, 2015 at 4:06

2 Answers 2

3
\$\begingroup\$

Do you have an actual, measured performance issue with accessing the properties file every time? If not, you're just introducing complexity to no end. What happens if the application crashes? All your updated properties are gone.

If you do have an actual, measured performance issue, consider keeping an in-memory copy of the properties. When one changes, update the in-memory version and spawn a low-priority thread to handle the write to the file. If you do, then you have to worry about the order those threads run in.

Definitely don't use Strings. If you're going to enumerate all your properties, use an enum. If you do, you shouldn't need reflection .. just walk down the values() of the enum.

\$\endgroup\$
2
  • \$\begingroup\$ I'm testing the first part of your comment, and will check the performace. I didn`t understand this - could you elaborate or give me an example - Definitely don't use Strings. If you're going to enumerate all your properties, use an enum. If you do, you shouldn't need reflection .. just walk down the values() of the enum. \$\endgroup\$
    – San Mor
    Commented May 8, 2015 at 16:53
  • \$\begingroup\$ Please check edited question. \$\endgroup\$
    – San Mor
    Commented May 8, 2015 at 18:14
2
\$\begingroup\$

You're approaching this the wrong way. The first rule regarding reflection in Java is: Don't use it if you can help it.

Reflection is slow, error prone and in general rather problematic.

What you want is a single instance of java.util.Properties, that you instantiate (and fill) at startup and then dispose of when terminating.

That's the simplest and clearest solution to this particular problem. The way through that class with all the reflection tricks associated is too complicated and error ridden as well as generally being a maintenance madness.

\$\endgroup\$
1
  • \$\begingroup\$ Vogel612 - I did get rid of reflection. Take a look at the updated code. I'm also using java.util.Properties variable as you mentioned. I`m happy with this approach. NOTE : The last edit with the updated code was rolled back. \$\endgroup\$
    – San Mor
    Commented May 11, 2015 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.