Java properties containing dollar-separated variables

I save the settings of my application in a properties file that I use in Ant and in a Java application. This may not be a good mark, but I find it very convenient to avoid duplication. The file contains variables such as:

usefulstuff.dir = ${user.home}/usefulstuff 

So that other people can run the program on * nix systems, provided that they have a folder of useful information in their home directory.

Now the exciting thing is that this properties file works fine in Ant (the variable gets permission /home/username ), and when I load the same file directly into a Java application, I get a line containing ${user.home}/usefulstuff , which not very helpful.

I load the details with this code in Ant:

  <loadproperties srcFile="myProps.properties"/> 

And in a Java application:

  FileInputStream ins = new FileInputStream(propFilePath); myProps.load(ins); ins.close(); 

Did I miss something? Perhaps there is a better way to load properties in a Java application than load() ?

+4
source share
2 answers

I donโ€™t think itโ€™s particularly โ€œexcitingโ€ that it works in Ant - Ant intentionally written for this :

Properties are key-value pairs, where Apache Ant tries to deploy the ${key} value at runtime.

and

Ant provides access to all system properties as if they were defined using the <property> task. For example, $ {os.name} expands to the name of the operating system.

If you need the same behavior, you need to implement the same logic. Perhaps you can directly use classes from Ant if they do what you want, and if you are happy to send the corresponding binaries (and respect them).

Otherwise, you can use the regular expression to find all matches - or (possibly simpler) iterations over all the properties of the system and make them a simple replacement.

+6
source

As John said, it should be too hard to write property management yourself. For instance,

 import java.util.*; public class PropertiesTest { public static void main(String[] args) { Properties props = new Properties(); props.setProperty("foo", "foo/${os.name}/baz/${os.version}"); props.setProperty("bar", "bar/${user.country}/baz/${user.country}"); System.out.println("BEFORE:"); printProperties(props); resolveSystemProperties(props); System.out.println("\n\nAFTER:"); printProperties(props); } static void resolveSystemProperties(Properties props) { Map<String, String> sysProps = readSystemProperties(); Set<String> sysPropRefs = sysProps.keySet(); Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String value = props.getProperty(name); for (String ref : sysPropRefs) { if (value.contains(ref)) { value = value.replace(ref, sysProps.get(ref)); } } props.setProperty(name, value); } } static Map<String, String> readSystemProperties() { Properties props = System.getProperties(); Map<String, String> propsMap = new HashMap<String, String>(props.size()); Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); propsMap.put("${" + name + "}", props.getProperty(name)); } return propsMap; } static void printProperties(Properties props) { Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String value = props.getProperty(name); System.out.println(name + " => " + value); } } } 
+2
source

All Articles