XML for Configurations

In this article, we look at the use of XML for configuration data. This differs from our XML coverage  that we are not using XML to transfer data between applications, or for generating a presentation layer; we are simply using XML to store data. To understand the motivation for using XML for configuration data, you need only write an application that uses extensive properties files, or code a server that is configured via files on a filesystem rather than command-line arguments. In both cases, the format of the files to supply information to the application becomes arbitrary and usually proprietary. The developer working on configuration often decides on a format, codes a file reader, and the application becomes locked into that format forever. Certainly this is not the most long-term view of application programming and development. As developers and system engineers realized the maintenance problems that an approach like this can cause (forgetting where a comma belongs, being unsure what marks a comment, etc.), it became clear that a standard was needed to represent this type of data that would not immediately cause an application's configuration mechanism to become proprietary. One standard solution that is being used today, but is still lacking functionality, is Java properties files and the java.util.Properties class. Introduced in the Java Development Kit ( JDK) 1.0, these constructs provide a more Javacentric means of storing data and configuration information. However, they do not provide for any sort of grouping or hierarchy. A client application had just as much access and visibility into a server's information as the server did into the client's data, and developers were unable to perform any sort of logical grouping within these files. In addition, having hierarchical configuration parameters had become popular; this nesting of information was difficult to accomplish in other solutions without creating even more complex (and still very proprietary) file formats. XML nicely solved all of these issues and offered a standard, simple way to represent application configuration information. The format also lends itself to being a multi-purpose administration tool. Consider that XML allows a generic application to be coded that can load a DTD or schema and then a configuration file, and allows a user to add, update, delete, and modify information with such a tool. Because XML was being used in many applications already, it became a natural extension to add parsing and handling of configuration files that were converted to XML. Applications that do not utilize XML can easily begin to use XML by introducing XML configuration files; this is much easier to do than to add support for XML data transferal or XML transformations. All in all, it seemed an excellent fit for a variety of applications. When the Enterprise JavaBeans (EJB) 1.1 specification was released, dictating that all EJB deployment descriptors would be in XML format, the use of XML for configuration information exploded. Many who were concerned about introducing the overhead of an XML parser or worried about the longevity of XML suddenly found themselves having to use XML to deploy their business objects in EJB servers. This made a migration of all application configuration data to XML logical and even decreased the complexity of many applications. In this article we look at how you can use XML for configuration data within your applications.

First we spend some time looking at a current use of XML for configuration data. The EJB deployment descriptor is examined with an eye towards important design decisions made in the specification of that file. This will prepare us to write our own configuration files in XML. With this file built, we look at coding some utility classes to parse and load this information into our XML-RPC classes, adding flexibility to our server and clients. Using the JDOM interfaces for parsing, we can easily load the configuration information. Finally, we end with a look at XML in relation to other important data storage mechanisms, databases and directory servers. This will cast our use of XML for configuration data in the light of the "real world" and help you make wise decisions about when to use XML as a data source and when not to.

EJB Deployment Descriptors

Before we begin creating our own configuration files and programs to read and use those files, a look at existing formats and patterns in this area will help. Although this is not a article about EJB, spending some time investigating the EJB deployment descriptors can aid us in understanding how XML-based configuration files work, as well as suggest ideas on how to structure our file format and data. We discuss some of the most important design decisions here and relate them to the EJB deployment descriptor. Before looking at the design of the deployment descriptor itself, though, we should look at why its overall EJB design lent itself to using XML at all. The EJB 1.0 specification required serialized

deployment descriptors; unfortunately, that was the only guideline given. This resulted in each EJB vendor providing a proprietary format for their server's deployment descriptors, and then forcing the application developer to run a tool (or even write their own tool) to serialize the descriptor. EJB, and Java in general, had lost its claim to WORA, Write Once Run Anywhere. XML provided a standard means of handling the deployment descriptor, as well as removing the need for proprietary tools to serialize the descriptors. In addition, Sun provides an EJB DTD that ensures each vendor's deployment descriptors conform to the same specifications, allowing EJBs to be highly platformand vendor-independent.

 

The Basics


As with any XML document, the EJB deployment descriptor has a DTD to which it conforms. A schema, as we have already discussed, will probably replace this in future revisions of the specification. In either case, the important concept here is that XML documents used for configuration, even more so than for other purposes, must have a set of constraints put upon them. Without constraints, the information could be incorrect or useless to a server, often causing an entire application to fail as a result. Once the constraints have been identified, the deployment descriptor begins with its root element, ejb-jar . Although this may seem a trivial item to note, the naming of a root element is an important part of authoring any XML document. This element faces the rather enormous task of having to represent all the information within the XML document it belongs to. Particularly when others may have to use or maintain your documents, proper naming here can avoid confusion, and poor naming can cause it. The relevant portions of an XML deployment descriptor that adheres to the EJB specification are shown here:

JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

This ejb-jar file contains assembled enterprise beans that are

Part of the employee self-service application.

...

Using namespaces (which were in their infancy when the EJB 1.1 specification was developed) can add clarity to the naming of your document's root and other elements. This aids in identification of the purpose of the document; consider the ambiguity removed by using a namespace such as DeploymentDescriptor or even simple EJB-DD in the EJB deployment descriptor. Any questions about the use of the document are removed when viewing these namespace prefixes on elements.

Organization


Just as naming is critical for document clarity, organization is crucial to the usability of your configuration files in XML. Not only do the organization and nesting of elements and attributes in your document help in understanding the purpose of a document, they can ensure that applications can share configurations and reuse similar information. It is equally important to know when not to try to store information across configurations. This is particularly relevant as we look at the EJB deployment descriptor; each EJB is intended to act independently of all others, knowing only the information supplied to it by its container. It is a problem if beans can operate with each other outside the strict confines designed by the bean developer, as performance and business logic can be subverted. For this reason, each EJB entry is completely independent of all others. In the following example, a session bean is described in XML:

The EmployeeServiceAdmin session bean implements the session

used by the application's administrator.

EmployeeServiceAdmin

com.wombat.empl.EmployeeServiceAdminHome

com.wombat.empl.EmployeeServiceAdmin

com.wombat.empl.EmployeeServiceAdmin-Bean

Stateful

Bean

This is a reference to a JDBC database. EmployeeService keeps a log of all the transactions being performed through the EmployeeService bean

for auditing purposes.

jdbc/EmployeeAppDB

javax.sql.DataSource

Container

In addition to the isolation of this session bean from any other beans, elements are used to logically group elements and data. The resource-ref element encloses information relevant to a particular environment entry. This makes it easy for the application parsing and using the data as well as developers and system administrators maintaining the application to locate and update information about the bean or EJB server.

 

Creating an XML Configuration File


To try to put some of this knowledge into use, we look at using an XML-based configuration file for the XML-RPC classes . Certainly this is an excellent example of using XML for configuration information; we already have an XML parser available (used in the XML-RPC server), and it is possible that we could use this same configuration file for both clients and servers. Additionally, this configuration could be edited by XML IDEs instead of our having to create a proprietary interface for editing the file in a proprietary format. This can reduce the code that needs to be written for complex applications. Before we start writing our configuration file, we need to define the information that will be in this file. The pieces of information we want to include are:

• Port for the XML-RPC server to start on

• Parser class for the server to use as a SAX driver

• Handlers for the XML-RPC server

• Class identifier

• Class name

• Hostname for the XML-RPC clients to connect to

• Port for XML-RPC clients to connect to

• Parser class for the server to use as a SAX driver

This provides all the information needed for both our clients and server to start without needing any user input other than the location of the XML configuration file itself. With these requirements in mind, let's begin writing the XML configuration file.

 

Getting Started

 

Just as in the case of the EJB deployment descriptor, our file must include the standard XML prolog information. This is simple enough, and the only other details we need to decide on are a namespace and root element for our document. Although in a production situation we might use a namespace indicative of the purpose of the document, such as XMLRPC or XmlRpcConfig, here we continue to use JavaXML to identify the configuration file with the examples in the rest of the article.The root element then becomes an identifier of what the document actually is used for; simply using xmlrpc-config seems a good choice for this. It is often the case, particularly in more complex XML documents, that the simplest solutions are the best ones. Naming XML elements and attributes is no exception to this rule.

With these initial determinations and decisions made, let's start creating our XML configuration file for our XML-RPC classes. The initial XML declaration and root element with namespace declaration are given here:

xmlns:JavaXML="http://www.oreilly.com/catalog/javaxml/"

>

Other options that can be added at this point include a reference to a DTD or schema to constrain the document as well as processing instructions to applications that might parse and use this configuration. For our example, we omit these, as our program will simply parse the document as is and return the needed configuration information to the XML-RPC server and clients.

 

Organization


With the skeleton of the configuration file set, organization of the file needs to be determined. This includes both grouping of elements and a determination of whether any configuration information will be shared across servers and clients. The best methodology for making organizational decisions is to group the file much as you would group the configuration information if writing it by hand. Our original information requirements are small, and this process is easy to perform.

The following pieces of information are simple, and we can consider them part of the information needed by our server:

• Port for XML-RPC server to start on

• Parser class for server to use as a SAX driver

The following pieces of information will be repeated numerous times, and can be grouped into a set

of handlers, with each handler within that set having a class identifier and a class name:

• Handlers for XML-RPC server

• Class identifier

• Class name

 

The XML-RPC client uses the last three pieces of information; however, the port used by the client is the same for the XML-RPC server, and the SAX driver is most likely the same as well. It makes sense to share this information so that changes only need to be made in one XML element, rather in separate elements for the client and server. With the port and SAX driver class being shared, it makes sense to also group the hostname into this set of shared information. Even though only the client uses it, it fits in well with the port number to use for XML-RPC requests.

• Hostname for XML-RPC clients to connect to

• Port for XML-RPC clients to connect to

• Parser class for client to use as a SAX Driver

By simply "talking through" the information to be included, we have determined that we have two basic groups of configuration information: "shared information" used by both the server and client, and " handler information," which has "handler" entries for each XML-RPC handler. This will result in two basic groupings in our configuration file, with the latter of these two having elements nested within it describing each grouping. We look at each in turn next.

Shared information


There is very little to note in adding a hostname, port number, and SAX driver class for our server and clients to use at startup and connection time. Even the element names for these three pieces of information are simple to arrive at: hostname, port, and parserClass. Again, simple solutions are generally the most effective. As an example of using attributes as well as elements, we add in an attribute for the port element named type. The idea is that the value of this element is either "protected" or "unprotected." When the port is protected, some additional actions would need to take place to connect, such as encoding the request through SSL. In our example XML-RPC classes, the server listens on an unprotected port; however, using this attribute adds flexibility if we want to use secure ports at a later point in the application's evolution:

newInstance

8585

org.apache.xerces.parsers.SAXParser

XML-RPC handlers


The first thing we want to do in defining our handlers is to ensure they are only used by our XMLRPC server. Although we have no other information besides the handler configuration applicable to only the server, it is possible and even probable that at some point, more server-specific information will be added to the configuration file. Rather than having our parser look for a specific set of elements (and adding to those elements when we add new configuration information), we can have it look for a server-specific element name, such as xmlrpc-server. Server applications can read this information, while clients can ignore it without having to know the specifics of the information contained within the grouping. It also makes the information's purpose easier to discern for human eyes. We use this element (xmlrpc-server) to enclose our handler information. We also should group all of our handlers together, and use an element simply named handlers to do this. Again, this grouping makes it simple to determine the purpose and use of the configuration information within the file. Add the configuration information needed for specifying the HelloHandler and Scheduler classes as XML-RPC handlers to the XML-RPC server


Like it on Facebook, Tweet it or share this article on other bookmarking websites.

No comments