Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuration Management in JavaEE

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:

  1. Default configuration when nothing else is specified (inside WAR file)
  2. 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

  1. I don't know if every container (which supports JavaEE) has such a nice feature
  2. I don't really want to have plain file access from a web application
like image 589
Markus Ratzer Avatar asked Oct 21 '12 08:10

Markus Ratzer


People also ask

What is configuration management in Java?

Configuration management (CM) is a governance and systems engineering process used to track and control IT resources and services across an enterprise.

What is configuration management explain?

Configuration Management is the process of maintaining systems, such as computer hardware and software, in a desired state. Configuration Management (CM) is also a method of ensuring that systems perform in a manner consistent with expectations over time.

What is an example of configuration management?

Configuration management can be used to maintain OS configuration files. Example systems include Ansible, Bcfg2, CFEngine, Chef, Nix, Otter, Puppet, Quattor, SaltStack, Terraform, Pulumi and Vagrant. Many of these systems utilize Infrastructure as Code to define and maintain configuration.

What is configuration file in Java?

A configuration file, often shortened to config file, defines the parameters, options, settings and preferences applied to operating systems (OSes), infrastructure devices and applications in an IT context. Software and hardware devices can be profoundly complex, supporting myriad options and parameters.


1 Answers

After talking with my colleagues and some research I've implemented the following for the host specific (external) configuration.

As I need a working directory for my application anyway, I decided to use this working directory also as the location for my external configuration. Therefore I either use an environment variable (e.g. MYAPP_HOME) or, if the variable is not set, the user's home folder (e.g. <user.home>/.myapp):

private Path discoverRootDirectory() {
    String myAppHome = System.getenv("MYAPP_HOME");

    if (myAppHome == null) {
        return Paths.get(System.getProperty("user.home"), ".myapp");
    } else {
        return Paths.get(myAppHome);
    }
}

The properties file will then be loaded as usual:

private void loadConfiguration() {
    properties = new Properties();
    // ...
    try (InputStream inputStream = Files.newInputStream(discoverRootDirectory())) {
        properties.load(inputStream);
    } catch (FileAccessException | IOException ex) {
        // ...
    }
}
like image 153
Markus Ratzer Avatar answered Sep 17 '22 16:09

Markus Ratzer