views:

1765

answers:

6

I have a static util class that does some string manipulation on a bit sensetive data. Prior to use of this class I need to initialize certain static variables with values, such as usernames/password, that I prefer to store in .properties file. I am not very familiar with how loading of .properties file work in Java, especially outside of Spring DI container.

Anyone can give me a hand/insight on how this can be done?

Thank you!

Addition: .properties file precise location is unknown, but it will be on the classpath. Sorta like classpath:/my/folder/name/myproperties.propeties

+6  A: 
  1. Check out java.util.Properties.

  2. You can use a static initializer. So on the top of the class you can do:


 static {
    Properties props = new Properties();
    InputStream steam = ...; // open the file
    props.load(stream);

    // process properties content
    String username = props.getProperty("username");
  }
notnoop
Sorry, I guess you were already formatting the code while I was doing it.
Michael Myers
You may need some exception handling, since I don't think exceptions can be thrown from within a static block.
Peter
RuntimeExceptions can be thrown from within a static block. You will need to handle checked exceptions for the file operations.
akf
Stream not closed?
erickson
The suggested implementation here was meant mainly for illustration. To make it production quality, you need to handle exceptions related to the file (e.g. security, existence, IOException), closing the connection within a finally block, handling encryption (I hope that he doesn't keep passwords in plaintext), etc
notnoop
+1  A: 

Use either:

ClassLoader.getResourceAsStream 
new FileInputStream(File)

to get the input stream depending on if the class is in or out of the classpath. Then use

Properties.load

to load the properties.

stevedbrown
A: 

It's been a while, but if I remember correctly you just do something like this:

Properties prop = new Properties();
prop.load(new FileInputStream(filename));

//For each property you need.
blah = prop.getProperty(propertyname);
patros
A: 

Well with static Properties it would make sense to initialize them as a Singleton which will be loaded once in a class. Here's an example:

class Example
{
    public final static String PROPSFILE = "test.properties";

    private static Properties props;

    protected static Properties getProperties()
    {
     if(props == null)
     {
      props = new Properties();
      props.load(new FileInputStream(new File(PROPSFILE));
     }
     return props;
    }

    public static User getUser()
    {
     String username = getProperties().getProperty("username");
     return new User(username);
    }
}

If you use relative Pathnames you should make sure, that your classpath is setup righ.

Daff
That's not a Singleton. It is simply a static variable and method. The question didn't require public access to the properties, but initialization of static members from a properties file.
Robin
Well personally I'm not a Fan of static Initialisation because it caused some trouble in a Project I was working on. I would recommend to use at least static Factory Methods where ever possible (I updated the example for that). But true, that wasn't actually the question.
Daff
+5  A: 

First, obtain an InputStream from which the properties are to be loaded. This can come from a number of locations, including some of the most likely:

  • A FileInputStream, created with a file name that is hard-coded or specified via a system property. The name could be relative (to the current working directory of the Java process) or absolute.
  • A resource file (a file on the classpath), obtained through a call to getResourceAsStream on the Class (relative to the class file) or ClassLoader (relative to the root of the class path). Note that these methods return null if the resource is missing, instead of raising an exception.
  • A URL, which, like a file name, could be hard-coded or specified via a system property.

Then create a new Properties object, and pass the InputStream to its load() method. Be sure to close the stream, regardless of any exceptions.

In a class initializer, checked exceptions like IOException must be handled. An unchecked exception can be thrown, which will prevent the class from being initialized. That, in turn, will usually prevent your application from running at all. In many applications, it might be desirable to use default properties instead, or fallback to another source of configuration, such as prompting a use in an interactive context.

Altogether, it might look something like this:

private static final Properties config;

static {
  Properties fallback = new Properties();
  fallback.put("key", "default");
  config = new Properties(fallback);
  try {
    InputStream stream = ...;
    try {
      config.load(stream);
    }
    finally {
      stream.close();
    }
  }
  catch (IOException ex) {
    /* Handle exception. */
  }
}
erickson