tzippy
tzippy

Reputation: 6638

Make Java Properties available across classes?

I chose to take properties file for customization of some settings. I use the following code to make a Properties Object available in a class

Properties defaultProps = new Properties();
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

Do I have to add this to every class? Probably not because then every class would open a stream to this file. But I'm not sure how to handle this properly. Should I make a class MyProperties and instantiate it in whatever class needs properties?

Thanks in advance!

Upvotes: 11

Views: 19659

Answers (8)

SirDarius
SirDarius

Reputation: 42899

If you only need one instance of your properties class you can use the singleton (anti?)-pattern.

It would look like a class like this:

public class MyProperties extends Properties {
    private static MyProperties instance = null;

    private MyProperties() {
    }

    public static MyProperties getInstance() {
        if (instance == null) {
            try {
                instance = new MyProperties();
                FileInputStream in = new FileInputStream("custom.properties");
                instance.load(in);
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return instance;
    }
}

Upvotes: 3

Nilesh
Nilesh

Reputation: 2168

Rather than loading properties in every class. Load it somewhere around main() and pass it to other classes via their constructors.

Don't share them globally. - Difficult to test - Against the abstraction (Global access, DAO can access user settings. it should be prevented by passing only what it needs.. not everything) - Classes lie what they need

Upvotes: 0

Courtney Christensen
Courtney Christensen

Reputation: 9555

Since this information is static across all instances, I recommend implementing the Properties class as a singleton. By using the static initialization block method, you can have it load the file automatically when the program starts up.

public class Properties {
  static {
    try {
      FileInputStream in = new FileInputStream("custom.properties");
      load(in);
      in.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  protected static void load(FileInputStream in) {
    // existing load functionality here
  }
}

You are still going to need an internal storage mechanism and accessor mechanism. These should also be marked static.

Upvotes: 0

fmucar
fmucar

Reputation: 14558

Why not use a static ResourceBundle ?

static final ResourceBundle myResources = 
          ResourceBundle.getBundle("MyResources", currentLocale);

Upvotes: 1

Péter Török
Péter Török

Reputation: 116266

Once you initialized defaultProps, you can make its contents available to other objects in your app e.g. via a public static accessor method, e.g.:

public class Config {
  private static Properties defaultProps = new Properties();
  static {
    try {
        FileInputStream in = new FileInputStream("custom.properties");
        defaultProps.load(in);
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
  public static String getProperty(String key) {
    return defaultProps.getProperty(key);
  }
}

This is the simplest approach, however it creates an extra dependency which makes unit testing harder (unless you provide a method in Config to set a mock property object for unit testing).

An alternative is to inject defaultProps (or individual configuration values from it) into each object which needs it. However, this may mean you need to add extra parameter(s) to lots of methods if your call hierarchies are deep.

Upvotes: 14

maaartinus
maaartinus

Reputation: 46422

This is a special case of making anything available globally. Using static methods is quite bad. A better but bad solution is using the sigleton pattern. Testing is the greatest problem here. IMHO, the best way is using Dependency injection, although it may be an overkill for small applications.

Upvotes: 0

jzd
jzd

Reputation: 23629

Load the properties once using and store the Properties somewheres that others classes can pull from. If that is a MyProperties class that references a static variable somewhere that is fine.

Upvotes: 0

Kent Murra
Kent Murra

Reputation: 244

There's too little information to determine what the best way to handle this would be. You may want to expose it using an accessor, or pass it into each class that requires it. Alternatively, you may pull out the properties that each class needs and pass their values into the class's constructor.

Upvotes: 0

Related Questions