Question

How can I use a properties file to store global variables in my application but also inject them into the application using public static final variables?

Having a look at this question, I was hoping to find a way that I could inject my static final variables into the application from a properties file. I was left dissapointed but eventually found out a way that I could have my cake and eat it too.

I'm posting this solution below to add to the compendium of SO...

Was it helpful?

Solution

My solution involves the concept of Global variables (which are apparently bad), so if you are not feint of heart then read on.

It is my belief that although we would like to all follow the functional programming craze and remove all concept of 'pulled' dependencies from our functions, there are some truths that need absolute grounding and thus a few sources of truth in the form of Global variables in a runtime application is actually helpful. but I don't want to start a flame war...

Solution

  1. Start with a public class named Globals (or something obvious like this)

  2. To Inject a property from a property file you need to establish the basename (or location) of the properties file, e.g. "com.example.myapp.core.configuration" may represent a configuration file in your core module with a physical url of jar:file:C:/jars/myapp.ear/core.jar!/com/example/myapp/core/configuration.properties. make this basename a static final variable:

    public static final String CORE_CONFIGURATION_BASENAME = "com.example.myapp.core.configuration";
    
  3. then define the property keys as private variables (for encapsulation), e.g.

    private static final String DOMAIN_PACKAGE_KEY = "myapp.domain.package.name";
    
  4. then define the property themself as a public final static variable, like so:

    public static final String DOMAIN_PACKAGE; //we leave it uninitialized on purpose.
    
  5. the above code will throw a compiler error when built, so we need to initialize it using the static block. to do this, we must first retrieve the resource bundle using the basename we defined:

    static {
        ResourceBundle bundle = PropertyResourceBundle(CORE_CONFIGURATION_BASENAME);
        ...
    }
    
  6. then we assign the final properties using the keys we define:"

    static {
        ResourceBundle bundle = PropertyResourceBundle(CORE_CONFIGURATION_BASENAME);
        DOMAIN_PACKAGE = bundle.getString(DOMAIN_PACKAGE_KEY);
    }
    

And there you have it. this will be initialized upon loading the Globals class so if you change the configuration properties with the values and want them reflected in your application, You will need to restart the application to force the classloader to reload the class.

altogether now:

package com.example.myapp.core.util;

import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

public class Globals {
    public static final String CORE_CONFIGURATION_BASENAME = "com.example.myapp.core.configuration";
    private static final String DOMAIN_PACKAGE_KEY = "myapp.domain.package.name";
    public static final String DOMAIN_PACKAGE; //we leave it uninitialized on purpose.

    static {
        ResourceBundle bundle = PropertyResourceBundle(CORE_CONFIGURATION_BASENAME);
        DOMAIN_PACKAGE = bundle.getString(DOMAIN_PACKAGE_KEY);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top