http://www.developer.com/

Back to article

Managing Your Configuration with JFig


April 1, 2004

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="admin@mycomp.com" />
      <entry key="senderAddress" value="webproj_dev@mycomp.com" />
   </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 Features

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 base 
    configuration also possible --> <section name="notification"> <entry key="senderAddress" value=.webproj_dev@mycomp.com. /> </section> </configuration>
    This feature provides many benefits, such as:
    • 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.
  • JFig stores all configuration files in a single common repository, ordered in a neat hierarchy. This helps while locating, managing, and modifying them.
  • JFig contains a component named JFigLocator, which can be extended and used (optional) to automatically locate configuration files not in the classpath, according to a user-defined search scheme.
  • Instead of hard-coding property values everywhere in configuration, JFig assigns values to these properties once (either manually or programmatically) and substitutes variables in their place at other locations. Whenever property values change, these changes are easily reflected in all places the values are referred to by using variables. This practice makes value modifications less error-prone. These variables are defined as [section_name] {key_name}.
    For example:
  • <section name="authentication">
          ......
       <entry key="userid" value="admin" />
          ......
    </section>
          ......
    <section name=" notification ">
          ......
       <entry key="receiverAddress"
              value="[authentication]{userid}@mycomp.com" />
    </section>
    
  • JFig easily integrates with other Java-based tools to allow developers to use JFig with their existing applications. Presently, it supports Maven, ANT, Log4j, and Weblogic. Work is in progress to include more tools. Check out JFig's home page for the latest updates.
  • The latest version, 1.4.1, of JFig provides means to convert and store existing non-JFig configuration files to a JFig-supported format, using JFig's substitution syntax. This makes switching to JFig with an existing configuration possible. Check out JFig's home page for the latest updates.
  • JFig provides a means to access system properties through JFig configuration files. One can substitute variables in place of hard-coding system properties to dynamically retrieve system properties, using the following syntax: value="$system_propert_name$"
    For example:
  • <entry key="class_Path" value="$CLASSPATH$" />
  • Other than XML-based configuration files, JFig also supports .ini files. This is useful for Windows-based applications. This article concentrates on XML-based configuration files only. Check out JFig's home page for .ini examples.

Putting JFig to Work

Requirements

To run, JFig requires the following .jar files, and their respective paths included in the classpath.

Installing JFig

Installing JFig is a pretty simple task. Just download the JFig source archive (jfig-1.4.1.zip or jfig-1.4.1.jar, lightweight with sizes 3 Mb and 50 Kb respectively, both platform independent), uncompress the archive in the desired location, and include that location's path in the classpath. Downloading jfig-1.4.1.zip is recommended because it also includes javadocs for the JFig API.

The next step (optional) would be integrating JFig with an existing application. As said earlier, at present JFig supports Maven, ANT, Log4j, and Weblogic. JFig provides the MavenFig and AntFig classes bundled with its distribution for Maven and ANT respectively, to perform such integration. Also, the JFig home page lists various techniques used for integration with Log4j, Weblogic, and other tools. Check it out for the latest and most detailed information on this subject.

Running JFig

After installing JFig and writing the necessary configuration files (such as Listings 1 and 2), it is time to write JFig code in the application using it. The API behind JFig tool can be used by the application to access the configuration info inside these files.

In the first class to be executed at application startup, include the following code:

Listing 3: JFig initialization code

try {
   JFig.initialize();

} catch (JFigException e) {
   e.getMessage();
}

Here, JFig class's method initialize() either initializes JFig's one and only instance (JFig is based on a Singleton pattern) or throws a JFigException. There is another version of this method, initialize(JFigLocator jl), where jl can be either a default or user-defined (extended) implementation of JFigLocator.

After initialization, configuration values can be accessed in the application by using the following JFig methods:

  • getValue(String section_name, String key_name): Returns a String value for a key with the given name in the section with the given name. Otherwise, it throws a JFigException.
    Usage:
    String uid = JFig.getInstance().getValue("authentication",
                                             "userid");
    
  • getVaue(String section_name, String key_name, String defaultValue): Returns the String value of the given key_name in the given section_name if the corresponding section and key exist. If they don't exist, defaultValue specified (optional) will be returned.
    Usage:
    String uid = JFig.getInstance().getValue("authentication",
                                             "userid", "guest");
    
  • setConfigurationValue(String section_name, String key_name, String value): Sets the configuration value; in other words, the value of the given key_name in the given section_name with the given value. Rarely used, because0 configuration values are usually set during the initial parsing of configuration files.
    Usage:
    JFig.setConfigurationValue(("authentication", "userid",
                                "developer");
    
  • reprocessConfiguration(): Reprocesses configuration on a running application and creates a new configuration directory containing all JFig values. Used when a change in the configuration values occurs.
    Usage:
    JFig.getInstance().reprocessConfiguration();
  • printConfigurationDictionary(): Prints all JFig values in a JFig dictionary to the console. Used for monitoring purposes.
    Usage:
    JFig.getInstance().printConfigurationDictionary();

Some other useful JFig methods, known as helper methods, are:

  • getIntegerValue(String sectionName, String keyName, String defaultValue)
  • getFloatValue(String sectionName, String keyName, String defaultValue)
  • getBooleanValue(String sectionName, String keyName, String defaultValue)
  • getArrayValue(String sectionName, String keyName)
  • getEntriesStartingWith(String sectionName, String keyName)
  • getValuesStartingWith(String sectionName, String keyValue)
  • getSection(String sectionName)
  • getSectionAsProperties(String sectionName)
  • addConfigEventListener(JFigListener listener)

See JFig javadocs for more methods and details of the whole JFig API.

After writing the necessary configuration files and including JFig code for accessing configuration info in an application code, the only thing that remains is to execute JFig itself. This is done by using the following command line:

java -Dconfig.filename=config_file
     [-Dconfig.location=classpath class_name]

For example:

java -Dconfig.filename= entServer.config.xml
     -Dconfig.location=classpath  com.EA.StartApp

Here, config_file will be the absolute path to a desired configuration file, and the fully qualified name of the class initializing JFig, if no JFigLocator exists. But, if a user-defined or even default implementation of JFigLocator exists, simply specifying the fully qualified classname will do.

Conclusion

JFig is a powerful yet lightweight and easy-to-use configuration tool that combines the OOP concepts of reusability and inheritance with a configuration mechanism. JFig allows developers to maintain more than one configuration for their applications, while providing a single common repository to save all these configurations and organize them in a neat heirachy.

JFig makes modifying a configuration on the fly and reflecting changes in running application possible. It also integrates easily with existing applications and can retain previous configuration settings of non-JFig configuration mechanisms.

According to Mr. Bruce Conrad, creator of JFig, new and improved versions of JFig are also under development presently. These versions will be based on the Preferences API of J2SE 1.4.2 and will include more features.

About Author

Mugdha Chauhan (formerly Mugdha Vairagade) is a senior IT consultant and author. An Open Source supporter, she frequently writes articles and tutorials on useful emerging Open Source projects. Major tech portals, including developer.com, IBM developerWorks, CNET Networks, Slashdot, and many eZines regularly publish her work. Her expertise and interests include Java, Linux, XML, wireless application development, and Open Source.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date