Search code examples
javapropertiesibatisdynamic

How To: Dynamically-defined properties in Java


How can I define some properties dynamically in Java. For now, I'm using a properties file, but I need to change these properties before installation, so these properties should be set in a file outside the jar (or install) file.

These properties define my IBatis connection.


Solution

  • Keep going with the .properties and load the file as a resource.

    If it is in the classpath it would be found.

    What I use, because it is much easier to me is a resource bundle instead.

    edit

    If the file is in your classpath you can loaded it either as a resource with: Some.class.loadResource(...) or what I do is use a ResourceBundle which does basically the same.

    For instance if I have:

    import java.util.ResourceBundle;
    
    public class ResourceBundleTest {
        public static void main( String [] args ) {
            ResourceBundle bundle = ResourceBundle.getBundle("connection");
            for( String key: bundle.keySet() ){
                System.out.printf("bundle[%s]=%s%n",key, bundle.getString(key));
            }
        }
    }
    

    I can load that file if is in the class path. The property is outside, in "some/nested/dir"

    $ls -l some/nested/dir/
    total 8
    -rw-r--r--  1 oscarreyes  staff  35 Jun 25 12:06 connection.properties
    $cat some/nested/dir/connection.properties 
    name=Oscar
    lastName=Reyes
    age=0x1F
    

    If I run it without adding that directory to my classpath it wont work:

    $java ResourceBundleTest 
    Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name connection, locale es_ES
        at java.ut...ceBundle.java:1427)
        at java.ut...urceBundle.java:1250)
        at java.ut...ceBundle.java:705)
        at Resourc...st.java:6)
    

    But if I add the directory to my classpath, then the file will be found easily.

    $java -cp some/nested/dir/:.  ResourceBundleTest 
    bundle[lastName]=Reyes
    bundle[age]=0x1F
    bundle[name]=Oscar
    $
    

    In a similar fashion, you can have a .jar file, and put your .properties file wherever you want, you just have to include it in your classpath.

    The equivalent using properties would be:

    import java.util.Properties;
    
    public class LoadProperties {
        public static void main( String [] args ) throws java.io.IOException {
            Properties properties = new Properties();
            properties.load( LoadProperties.class.getResourceAsStream("connection.properties"));
            properties.list( System.out );
        }
    }
    

    But for some reason I prefer the resource bundle.