Managing Your Configuration with JFig
Importance of Configuration
Most applications (be they desktop, Web-based, or large enterprise applications) use some kind of configuration mechanism by which users can modify application configurations partly/completely to change the application's behavior according to their needs or the environment the application runs in. Configuration plays an important role during application development as well, because developers have to configure an application under development for different platforms and different phases of the development cycle.
In the case of Java applications, various configuration mechanisms can be used, such as shell scripts, runtime command line options, property files, XML-based configuration files, and even hard-coding the configuration if the application is small in size (though it is not recommended). Among these techniques, XML-based configuration files are the most preferred and commonly used for their simplicity and flexibility. Various Java-related tools, such as ANT and Carbon, make use of XML-based configuration files to simplify the configuration process.
The Need for JFig
Developers often have to configure and reconfigure their applications, according to the various environments their application is intended to run in during the development, testing, or production phases. In many cases, there may be more than one configuration for each phase, each different from the other.
Manually maintaining these configurations is a tough task, especially in the case of large applications, such as enterprise applications that have many different configurations. This maintenance task spans from saving to locating a relevant configuration to tracking changes in the configurations. It is difficult to get back to a previously known good configuration if the current one proves error-prone, in case no backup mechanism exists for previous configurations. Another problematic area is making modifications in the configurations, such as changing a configuration by hand, which is error-prone and time-consuming. These changes should be reflected in all relevant positions in the application, and, if not done properly, may result in bugs or even an application crash.
Most of these problems can be solved if an efficient configuration management tool is used, one that manages the configuration efficiently and automates a large part of the maintenance procedure/task. Among many such available tools, including Jconfig, Commons Configuration from Jakarta, and so forth, is an easy-to-use and lightweight tool called JFig. An Open Source tool presently in version 1.4.1, JFig can be downloaded for free with a LGPL license from Sourceforge.
JFig is a powerful yet easy-to-use configuration tool for Java applications. It allows developers to maintain more than one configuration for their applications, corresponding to different environments their application is intended to run in. JFig saves all these configurations in one common repository in a neat hierarchy, thus simplifying the location, management, and modification of different configurations. JFig also allows a developer to modify the configurations to make changes "on the fly" in the running application, thus saving time and efforts used in locating relevant configurations, making changes, stopping and restarting/redeploying the application to reflect these changes.
A Simple Configuration File
Listing 1 shows a simple JFig configuration file, named entServer.config.xml, where entServer is named host. This is so because JFig by default searches for configuration files with names as <hostname>.config.xml. But, it is possible to change this behavior and use another filename by using the customized JFigLocator (See JFig Features section).
Listing 1: JFig configuration file entServer.config.xml
<configuration> <section name="WebProject"> <entry key="instance" value="base" /> <entry key="httpHost" value="entServer" /> </section> <section name="authentication"> <entry key="userid" value="admin" /> <entry key="pword" value="x98oln1wq" /> <entry key="role" value="administration" /> <entry key="rights" value="all" /> </section> <section name="notification"> <entry key="notificationType" value="general" /> <entry key="receiverAddress" value="email@example.com" /> <entry key="senderAddress" value="firstname.lastname@example.org" /> </section> </configuration>
The configuration file entServer.config.xml contains various configuration properties defined in the <entry> elements. The key attribute of <entry> specifies the property name, whereas the value attribute specifies a property value. All these properties are grouped together in relevant <section> entries having an attribute name to specify names to identify them.
Note: All <section> and <key> strings are case-insensitive.
JFig is loaded with a few innovative features that make it stand out. These features are listed below:
- JFig combines the OOP concepts of reusability and inheritance with the configuration mechanism by allowing a configuration to serve as a base that can be "extended" i.e. included by new configurations. Thus, instead of being created from scratch, a new configuration will "inherit" properties of the base configuration, maybe "override" desired base properties by layering new property values over old ones, and introduce new properties in the configuration. Listing 2 shows the webproject.prod.xml configuration file that includes entServer.config.xml from Listing 1.
Listing 2: JFig configuration file develop.config.xml
<configuration> <!-- Extending parent configuration --> <include name="entServer.config.xml"/> <!-- Overriding all entry values of a section in parent configuration--> <section name="authentication"> <entry key="userid" value="admin" /> <entry key="pword" value="x98oln1wq" /> <entry key="role" value="administration" /> <entry key="rights" value="all" /> </section> <!-- Overriding only select entry values of a section in baseThis feature provides many benefits, such as:
configuration also possible --> <section name="notification"> <entry key="senderAddress" email@example.com. /> </section> </configuration>
- Previous configurations are not lost and there is no need to create new configuration from scratch. Reverting to a previous configuration is easy.
- A clean hierarchy of configuration files, which is simple to understand and maintain.
- New configurations need to contain only those configuration properties that are layered upon corresponding properties of its parent. Remaining parent properties are implicitly inherited by the new configuration. As a result, new configuration files get smaller in size, making modifications and error-detection simpler.