Reputation: 1331
Problem statement
I have a properties file that's accessed throughout my java project.
Example contents of my .properties
file:
appName=MyApp
appType=TypeA
Let's say I access the single property, appName
, all throughout my java project
props.getProperty("appName");
I don't want to iterate through the properties file to get the property value; I'm just simply getting a single property value from the properties file. But I don't like the fact that I have to access the property by using a hardcoded string because it can lead to maintenance issues (i.e. changing all instances of the hardcoded string).
My current approach
In my current approach, I have a utility class that creates static final variables representing the key names in the properties file, and then I use that variable to access the property value:
public static final String APP_NAME = "appName";
...
props.getProperty(APP_NAME);
But this seems like overkill because it's being redundant, and still a potential maintenance concern. The key already exists in the properties file, and I'm declaring them again in my utility class.
Is there a more "maintenance-free" way of accessing the key name in my code when using the get methods to access property values?
Upvotes: 4
Views: 6375
Reputation: 2336
A colleague and I are facing a very similar issue at the moment, and we did some research to see if this could be solved using reflection. Unfortunately, we did not manage to solve it, but I will try to elaborate on our problem and strategy. Perhaps someone clever can use our baseline to build something that overcomes the limitations that set us back.
Problem statement: We want to read values in a properties file and assign these values to fields in a Java object (a settings object). The key names do not matter for us and as such it would be optimal to simply use the names of the Java fields as the key names.
This would bring two great benefits:
We planned on defining a method in the super class that would use reflection to get all instance fields. Onward from here, our strategy would be to loop through all fields and:
Using this approach, one would be able to add a new property simply by adding a new instance field. No extra code for reading nor writing the new property would be required.
Unfortunately this is not feasible due to two issues:
Class#getDeclaredFields()
might deny access.Upvotes: 0
Reputation: 1781
No, you're doing it right. And it's actually fairly maintenance-free.
Using Java Enums would be slightly preferable - i.e.
public class PropertiesWrapper {
private final Properties props;
...
public String get(MyEnum key) { return props.get(key.toString());
}
The reason is that even if you make that String a constant, you can never change it without recompiling all code which uses the constant - because the compiler will replace the constant with "appName" at compile-time.
If you use enums and remove an enum constant, code will still need recompiling, but it won't appear to be fine when it's actually now asking for the wrong thing. Also, by using toString()
instead of name()
to get the property name, you are free to override toString()
in your enum to return something different than the constant name.
The down-side of using enums is that the system can't look up anything which was not known at compile-time without some alternate way to access the Properties
.
Upvotes: 3
Reputation: 67310
There might be a library out there that will read a properties file and generate it into a source file with getters on it. You'd then have to compile that source file with your code. That would be a pretty nifty library. But, if this doesn't exist, I don't think there's any other way to do this.
Even if it exists, I don't see how it would be able to know that key1
is a String
and key2
is an Integer
. You'd still probably have to cast somewhere. That, or maintain a separate metadata file and then you're back to more maintenance.
The problem is, you can change the property file keys at any time and the compiler has no way of knowing you did it.
The best I can give you are libraries meant for reading configuration files. Check out the Apache Configuration library.
Upvotes: 1