My Goal
I’ve got a JavaEE environment (in my particular case it’s a Glassfish Web Profile) and I want a container independent way of configuring my application with the following features:
- Default configuration when nothing else is specified (inside WAR file)
- Custom configuration (outside WAR file) in two layers:
- Host specific settings (in an external properties file; e.g. some working directory)
- Application specific settings (in database; e.g. mailbox size)
My wish would be that there are as few preconditions as possible (the only one now is a JNDI datasource) to deploy and run my application (Set up JNDI datasource, deploy WAR file, have an optional .properties file in some configuration folder and - done).
This leads me to my first question: Is this a common/good/useful setup or is it unnecessarily complicated and/or very exotic?
My Idea (so far)
Default Configuration
The default configuration would be in a properties file:
src/main/resources/config/default.properties
An application scoped bean reads this properties on initialization as described here:
@Named
@ApplicationScoped
public class Configuration implements Serializable {
...
@PostConstruct
public void initConfiguration() {
loadDefaultConfiguration();
}
private void loadDefaultConfiguration() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try (InputStream input = classLoader.getResourceAsStream("/config/default.properties")) {
properties.load(input);
} catch(IOException ex) {
LOGGER.error(...);
}
}
}
Application Specific Settings
These settings will be stored in a database table with key and value columns. They'll be always accessed via an EntityManager, hoping the caching of the JPA implementation will be clever :). The advantage here is, that these settings can easily be changed while the application is running.
@Named
@ApplicationScoped
public class Configuration implements Serializable {
...
public T getProperty(final PropertyKeyEnum key, final Class<T> type) {
if (key.getSource() == PropertySourceEnum.DATABASE) {
return configurationDao.getByKey(key.getKey(), type);
}
...
}
}
Host Specific settings
Finally, here is my main problem:
How do I access an external properties file in a container independet way? The user shall be able to just place a myAppName.properties
file into the default configuration folder of the container and the application shall be able to find and load this file (at least on application startup).
My Environment
- JavaSE 7
- JavaEE 6
- Glassfish 3.1.2 Web (but this should not matter ;) )
Update
I've found a place in the admin area of Glassfish where you can specify some system properties which are easily accessable:
System.getProperty("myApp.propertyName");
This could be used to store the path to the external .properties file, but I'm not sure if this is a clean way because
- I don't know if every container (which supports JavaEE) has such a nice feature
- I don't really want to have plain file access from a web application