views:

1466

answers:

4

Our code uses a lot of system properties eg, 'java.io.tmpdir', 'user.home', 'user.name' etc. We do not have any constants defined for these anywhere (and neither does java I think) or any other clever thing for dealing with them so they are in plain text littered throughout the code.

String tempFolderPath = System.getProperty("java.io.tmpdir");

How is everyone using system properties?

+5  A: 

I would treat this just as any other String constant you have scattered throughout your code and define a constant variable for it. Granted, in this case "java.io.tmpdir" is unlikely to change, but you never know. (I don't mean that Sun might change the meaning of "java.io.tmpdir", or what system property it points to, but that you might change your mind about what system property you need to read.)

If you're only using a particular property within one class, then I'd define the constants right in that class.

private final String TEMPDIR = "java.io.tmpdir";

If you're using the same properties in different classes, you may want to define an static class of your own to hold the constants you use most often.

public final Class Prop {
    public static final String TEMPDIR = "java.io.tmpdir";
    ...
}

Then, everywhere you need to use that constant just call it using

System.getProperty(Prop.TEMPDIR);
Bill the Lizard
But where would you do that? Make some sort of constants only interface somewhere for just system properties? Never been a big fan of them really. Any suggestions?
willcodejavaforfood
I added a couple of different suggestions, but I think for constant strings you in a lot of different classes, the interface you describe is the best way.
Bill the Lizard
Fair enough. Daft question really :)
willcodejavaforfood
Seems like you knew the answer, you just didn't like it. :)
Bill the Lizard
Wanted some confirmation I guess :)
willcodejavaforfood
+1  A: 

I'd treat these as any other constant, probably with a P_ or PROP_ prefix, and put them in an appropriate constants class.

If you use lots of them, I'd even consider splitting them out to a PropertyNames constants class:

public final class PropertyNames
{
  private PropertyNames()
  {
     // no instantiation
  }

  public static final String P_VAR_DIRECTORY = "org.acme.app.varDir";

  public static final String P_TMP_DIRECTORY = "java.io.tmpDir";
}

Finally, I would seriously considering namespacing the property names themselves, with the standard reverse domain name used for packages. This is just to avoid clashing with third-party properties consumers.

jamesh
These properties are not defined by me, they are system properties and I cannot namespace them.
willcodejavaforfood
+2  A: 

if you are using it in multiple places it might be a good idea to write a class to encapsulate reading the property and maybe other properties.

so maybe something like: Configuration.getTemporaryDirectory()

+1  A: 

Since the question title is extremely broad, I'll throw in another good practice you should consider when using system properties. Access to system properties can by denied by the SecurityManager, so you may need to access them through a PrivilegedAction, like this:

String tmpdir = AccessController.doPrivileged(new PrivilegedAction<String>() {
  public String run() {
    return System.getProperty("java.io.tmpdir");
  }
});

Use a privileged action when your code constrains a sensitive action so that it will be safe even if malicious code invokes it.

For example, it would be unsafe to use a privileged action in a method like OutputStream open(File file). Untrusted code could invoke it, and use your code's privileges to write anything, anywhere.

However, if you had a method that saved user preferences for your application to a file you choose, that would probably be safe. A malicious caller can't choose the file location or its contents; those are specified by your code. So, your method can use a privileged action to allow it to be invoked by unprivileged code.

erickson