In java, we set system properties with System.SetProperties(Key, Value). I have the following queries related to it.
On what occasion we set the system properties in our code?
How do we determine the Key? i.e. How we will know what exact string we should give for Key?
Your question is so generic that any answer will be vague. You will probably get much better answers if you can be more specific.
On what occasion we set the system properties in our code?
This is like asking "when should we use the + operator". The answer, not too surprisingly, is "only when you need to".
System properties let you configure parts of the Java runtime (or your application server, etc) to do things differently. When you find an issue and it turns out the correct solution to the problem is to configure the Java runtime to modify its behaviour, that's when you need to find whether there is a system property. If there is, you need to set it to a value that gets you the behaviour your want.
How do we determine the Key? i.e. How we will know what exact string we should give for Key?
Through documentation, really. Lets say you run into a problem whre foo.bar() doesn't do what you think it would. Or it breaks in a case that's important to you. You should read the documentation for foo.bar(). It might say that you can change the behaviour by setting a system property. Then you set that system property to the value mentioned in the documentation.
Watch out: some system properties can not be set at all. Or rather, you can set them, but changing them after your program has started (main(string[]) has been called) has no effect.
I have this little snippet I use to see all the currently set system properties and their values. Helps with exploration and getting some ideas:
final String SEPARATOR = "=";
Properties properties = System.getProperties();
for (Object property : properties.keySet()) {
String prop = (String) property;
System.out.println(prop + SEPARATOR + properties.getProperty(prop));
}
You almost never set system properties. One use case is test automation: if the system under test behaves differently based on system properties, it makes sense to set them in the code that sets up the test environment. In regular application code you don't see it happen often.
If you're creating properties of your own, you can use anything you want as the key. Most people use the name of their project as the namespace so that the properties they use won't conflict with properties from libraries or other projects. This means the keys will have the form myproject.myproperty.
Related
What's the correct way to access the Properties() object after loading it with a .properties file?
One way I've used in the past is to just store each Properties object in a static variable in a utility class and access it through there. However I've been thinking that it might be better to actually create a wrapper class with some utility functions? Not sure if that would be helpful. Most examples I've found just concern themselves with how one loads a properties file but not what should happen after that.
Is there a generally approved way to do it and what are its pros and cons?
Just like Rob Conklin said, it's probably good to keep a level of abstraction in order to (in the future) be able to switch out the properties-file based storage.
However, you can set merge your properties with System.getProperty() to get easy access from wherever in your program
FileInputStream propFile = new FileInputStream("myProperties.properties");
Properties p = new Properties(System.getProperties());
p.load(propFile);
// set the system properties
System.setProperties(p);
Whichever properties you set latest will override the others (if the names collides)
You can then later access the property simply with
System.getProperty("propName");
Do yourself a huge favor, and create a DAO around your properties file access. In most systems I've worked on, we always wished we had this abstraction, it allows properties files to become database driven at some future point.
You can cache it inside the DAO as a static variable, but that becomes hidden from the client.
I am developing a Java program that retrieves data from various sources, manipulates the data and then sends the data to various destinations. I need to allow the user to define in a properties file the data sources, the data destinations and the modules used within the program to process the data.
I would envisage the properties file looking something like the following...
dataFlow1 = dataProcessorTypeA
dataFlow1.source = mySource1
dataFlow1.destination = myDestination1
dataFlow2 = dataProcessorTypeA
dataFlow2.source = mySource2
dataFlow2.destination = myDestination2
dataFlow3 = dataProcessorTypeB
dataFlow3.source = mySource3
dataFlow3.successDestination = mySuccessDestination3
dataFlow3.failureDestination = myFailureDestination3
...
dataFlow99 = dataProcessorTypeZ
The properties associated with each data flow will be dependent upon the module selected. So in the example above "dataProcessorTypeA" needs the "source" and "destination" properties to be set, whereas "dataProcessorTypeB" needs the "source", "successDestination" and "failureDestination" properties to be set. In the example "dataProcessorTypeA", "dataProcessorTypeB", and "dataProcessorTypeZ" would be classes within the program.
I have used properties files in the past to do simple "property=value" type configuration but I don't understand how this type of configuration can be achieved or what words I should use to search on Google to look for similar examples of what I'm trying to achieve. I also want to avoid hardcoding lots of logic into the program read the properties file as new modules may be added in the future. I'm assuming this will be similar to the way JavaBeans are configured with getters and setters.
What I want to achieve is similar to the way a user can configure Apache log4j to use multiple appenders by setting the following in the log4j properties file...
log4j.appender.ca=org.apache.log4j.ConsoleAppender
log4j.appender.ca.layout=org.apache.log4j.PatternLayout
log4j.appender.rfa=org.apache.log4j.RollingFileAppender
log4j.appender.rfa.File=example.log
I've looked through the PropertyGetter.java file in log4j and I can see that it makes use of reflections and introspection however I don't have a sufficiently deep understanding of the concepts to understand what's going on.
What I don't understand is how "log4j.appender.ca" can be created as an object, configured to use org.apache.log4j.ConsoleAppender and then how log4j knows to look for "log4j.appender.ca" when processing log messages. My question isn't really related to log4j but I'm using to illustrate the type of type configuration I'm looking to achieve in my own program.
Apache Shiro also provides a similar mechanism allowing the user to customise how the framework operates. I've looked through the ReflectionBuilder.java file in Shiro and can see that the Commons-BeanUtils library is being used, but again I'm somewhat out of my depth in understand what's happening within the code.
So in summary my question is can anyone provide me with a better understand of how frameworks such as log4j and Shiro allow for this type of configuration to be performed or give me some pointers in terms of what I should be searching for please?
Take a look here, and use with Properties class.
With Class.forName() you can find a class given its full qualified name.
No need for framework: use StringTokenizer(propertyname, ".") then each token represents one level of the nested map, except the last/leaf is the value.
This is handled by
Map<String,Map<String,..>>
So "dataflow1" is a key in first level map, with values "source" and "destination" at level 2, and then leaf/data values of "source1" and "destination1"
I've got a "normal" Java PropertyResourceBundle that's based on a stack of .properties files. In a few places, it would be much more convenient to operate on a Properties object based on the correct translated .properties file instead of the ResourceBundle. Is there a convient way to "cast" the ResourceBundle to a Properties?
What'd I'd like is something like this:
Locale currentLocale = MagicLocaleFactory.getLocale();
ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);
Properties myProperties = myResources.magicallyProduceAPropertiesObject();
So afterwords, the myProperties object behaves as if it had been instantiated from the same .properties file that ResourceBundle.getBundle() went and found.
There are a few ways to do this "by hand"; for example, iterating though the set of key-value pairs of the ResourceBundle and installing them in a fresh Properties object, but I was hoping there was a better, or at least shorter, way to do it.
Edit:
To answer the obvious "but, WHY?" question, the case is this: we're retrofitting a long-existing desktop java program for i18n. The program is already pulling strings from a Properties object backed by a single .properties file. We're replacing the single file with multiple files and "promoting" the Properties object to a resource bundle. The problem, such as it is, is that the method to get a key on Properties is getProperty, whereas for ResourceBundle it's getString or getObject. Changing where the Properties object comes from before it gets passed around the program and has strings pulled out is very easy. Changing the actual method call is... less easy. Sure, you can pretty much search and replace for that, but then instead of just changing the one class that loads the properties, we have to touch, essentially, every single source file. (Yeah, there's a lot of text in this thing.) We were hoping we had missed a way to to use the ResourceBundle's multiple .properties with fallback mechanism without having to rewire the entire app. (Gratuitous Gandalf quote: "There never was much hope. Just a fool's hope.")
There is no built-in way to do what you want, but as you said, it isn't difficult to do it yourself: the basically have the same interface, and copying the keys and values from the bundle to the properties is easy.
There is a caveat, though. Although the interface is similar, the implementation is not: the resource bundle has an inheritance model which allows returning the value in foo.properties if it isn't defined in foo_fr_FR.properties and foo_fr.properties. So copying all the entries won't get you the same properties as it they had been loaded from the properties file. It will get the entries of the properties file and the properties of all its parents. But I guess you knew that since you're talking about a stack of properties files.
You haven't stated why you would prefer a Properties over a ResourceBundle, so it's hard to give you a better answer.
Another solution would be to simply load the properties yourself:
Properties props = new Properties();
properties.load(MyClass.class.getResourceAsStream("MyResources_" + locale + ".properties")
This way, you would get only the entries from the specific properties file.
There in none and for the good reason: ResourceBundle is meant to contain properties in different languages, so that it would load *and fall-back appropriate file – when you ask for let's say messages with de-AT locale (German, Austria), it will fall-back to German if it is able to find one or to your base properties file (messages.properties) in other case.
I don't really know what is your use case here (maybe it is simply achievable in a different way?) but it seems that the only way is to read directly from properties file and unfortunately imitate the mechanism I mentioned above (the tricky part are Portuguese Brazil and Chinese Traditional which should not fall back to their "default" languages ("pt" and "zh" respectively)).
Another solution is iterate on keys and puts all pair in a properties object, You can use convertBundleToProperties:
static Properties convertBundleToProperties(ResourceBundle resource) {
Properties properties = new Properties();
Enumeration<String> keys = resource.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
properties.put(key, resource.getString(key));
}
return properties;
}
I have been using quite a lot of
System.getProperty("property")
in order to obtain environmental information. However, it seems to me that Sun prefers the following :
(String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("property"));
The strange thing is that this code involves a cast and as a result should be slightly slower than the
System.getProperty
implementation, that only uses a security manager and then instantly fetches the property from the instance variable props. My question is why did Sun chose to use the second method to obtain most environmental variables in their code internally, while
System.getProperty
seems like the faster way to go?
Both methods have a different meaning, and thus the right one has to be used depending on what the current code needs to do.
The code System.getProperty("property") says "Give me the value of the property, if the current security context allows me to read it."
The code that uses doPrivileged says "Give me the value of the property, if the current class (where this line of code is in) is allowed to read it."
The difference comes into play, when the protection domain of the current class is different from the currently active security context.
For example, consider a framework which executes the code of a plugin, which is untrusted. So the framework uses a SecurityManager to restrict the actions of the untrusted plugin code. But of course the plugin may call some methods of the framework, and suppose that one of these methods needs to read a property. Now as the method is called from untrusted restricted code, it is itself restricted and thus reading the property would fail. But of course the framework trusts itself and wants itself to be able to read that property, even in the case that somewhere in the call stack is untrusted code. That's when you need to use doPrivileged. It basically says "no matter what is up there in the call stack, I am a piece of framework code, and I am allowed to do whatever the framework code is allowed to do". So reading the property using the second method succeeds.
Of course one needs to be careful when using doPrivileged in order to not let the (untrusted) calling code do to much. If, for example, the framework code offers the following method to the plugin:
public String getProp(String key) {
return (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(key));
}
this would completely invalidate the policy that the untrusted code is not allowed to read system properties, because it can just use your method.
So use this method only when you know it is safe to do it, and only when you need it (which is, when you want your code to be able to do more than some other code should be able to do directly). Inside a normal application (which usually runs with no SecurityManager or the same security context for all code), there is no difference and the first method should be used.
I would recommend to stick with System.getProperty() since sun.security.action.GetPropertyAction seems to be proprietary to SUN and will not work on all Java VM implementations. Even the compiler warns you about it as:
warning: sun.security.action.GetPropertyAction is Sun proprietary API and may be removed in a future release
To understand what it actually means see this answer.
The reason to use a class like sun.security.action.GetPropertyAction is to avoid loading several, basically identical classes.
If you wrote:
(String) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<java.lang.String>() {
String run() {
System.getProperty("property");
}
}
);
Each time you wanted to get a system property, you would load a new class for each getProperty call. Each class takes system resources and lives as long as the containing ClassLoader (forever for the bootclassloader).
Check out the javap output for more details:
javap -c -v -p sun.security.action.GetPropertyAction
I'm at the point in my first real application where I am adding in the user settings. I'm using Java and being very OO (and trying to keep it that way) so here are my ideas:
Load everything in the main() and
pass it all 'down the line' to the
required objects (array)
Same as above, but just pass the
object that contains the data down
the line
Load each individual setting as
needed within the various classes.
I understand some of the basic pros and cons to each method (i.e. time vs. size) but I'm looking for some outside input as to what practices they've successfully used in the past.
Someone should stand up for the purported Java standard, the Preferences API... and it's most recent incarnation in JDK6. Edited to add, since the author seems to savvy XML, this is more appropriate than before. Thought I believe you can work XML juju with Properties too, should the spirit take you.
Related on SO: Preferences API vs. Apache solution, Is a master preferences class a good idea?
(well, that's about all the standing up I'm willing to do.)
Use a SettingsManager class or something similar that is used to abstract getting all settings data. At each point in the code where you need a setting you query the SettingsManager class - something like:
int timeout = SettingsManager.GetSetting("TimeoutSetting");
You then delegate all of the logic for how settings are fetched to this single manager class, whose implementation you can change / optimize as needed. For instance, you could implement the SettingsManager to fetch settings from a config file, or a database, or some other data store, periodically refresh the settings, handle caching of settings that are expensive to retrieve, etc. The code using the settings remains blissfully unaware of all of these implementaton decisions.
For maximum flexibility you can use an interface instead of an actual class, and have different setting managers implement the interface: you can swap them in and out as needed at some central point without having to change the underlying code at all.
In .NET there is a fairly rich set of existing configuration classes (in the System.Configuration) namespace that provide this sort of thing, and it works out quite well.
I'm not sure of the Java equivalent, but it's a good pattern.
Since configuration / settings are typically loaded once (at startup; or maybe a few times during the program's runtime. In any way, we're not talking about a very frequent / time-consuming process), I would prefer simplicity over efficiency.
That rules out option number (3). Configuration-loading will be scattered all over the place.
I'm not entirely sure what the difference is between (1) and (2) in your list. Does (1) mean "passing discreet parameters" and (2) mean "passing an object containing the entire configuration"? If so, I'd prefer (2) over (1).
The rule of thumb here is that you should keep things simple and concentrated. The advantage of reading configuration in one place is that it gives you better control in case the source of the configuration changes at some point.
Here is a tutorial on the Properties class. From the Javadocs (Properties):
The Properties class represents a
persistent set of properties. The
Properties can be saved to a stream or
loaded from a stream. Each key and its
corresponding value in the property
list is a string.
A property list can contain another
property list as its "defaults"; this
second property list is searched if
the property key is not found in the
original property list.
The tutorial gives the following example instantiation for a typical usage:
. . .
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
// create application properties with default
Properties applicationProps = new Properties(defaultProps);
// now load properties from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
. . .
You could, of course, also roll your own system fairly directly using a file-based store and an XML or YAML parser. Good luck!
We have recently started using JSR-330 dependency injection (using Guice from SVN) and found that it was possible to read in a Properties file (or any other map) and bind it inside Guice in the module in the startup code so that the
#Inject #Named("key") String value
string was injected with the value corresponding to the key when that particular code was called. This is the most elegant way I have ever seen for solving this problem!
You do not have to haul configuration objects around your code or sprinkle all kinds of magic method calls in each and every corner of the code to get the values - you just mention to Guice you need it, and it is there.
Note: I've had a look at Guice, Weld (Seam-based) and Spring which all provide injection, because we want JSR-330 in our own code, and I like Guice the best currently. I think the reason is because Guice is the clearest in its bindings as opposed to the under-the-hood magic happening with Weld.