Previous Up Next

Chapter 1  Introduction

1.1  Purpose of this Manual

This manual provides a reference for the application programming interface (API) of Config4J. This manual does not provide a beginner’s tutorial on Config4J. You can find such a tutorial in the Config4* Getting Started Guide.

The rest of this chapter discusses the principles that underpin the API of Config4J. Knowledge of these principles makes it easier to understand the API. The chapters that follow discuss the API of individual classes.

1.2  Package

All the classes of Config4J are defined in the org.config4j package. For conciseness, the package prefix is not explicitly stated in the discussion of classes and operations in this manual.

1.3  Portability

One of the design goals of Config4J is portability. Of course, Java source code (and byte code) is portable across many operating systems, so that aspect of portability is obtained trivially. However, another aspect of the portability goal is that Config4J should compile with both new and older Java compilers. For this reason, Config4J avoids using relatively new language features. In particular, Config4J avoids language features introduced in Java 5: annotations, generics and enumerations. Config4J also avoids use of the assert keyword, which was introduced in Java 1.4. You should be able to use Config4J with Java 1.3 or newer.1 Config4J may even work with Java 1.2, but I have not tried that.

1.4  Error Reporting

The Config4J parser does not make any attempt at error recovery. Instead, it stops at the first error it encounters, and reports the error by throwing an exception. The lack of error recovery helps to keep the implementation of the parser simple. It also simplifies the public API because the ability to report multiple parsing errors would have required a more complex API.

1.5  Specifying Scoped Names

Many of the operations in Config4J work with scoped names, for example, foo_srv.log.dir. Typically, the first part, foo_srv, is a scope for a particular application, and the remainder, log.dir, is a configuration variable used by that application. It can be useful to change the application name (foo_srv) without needing to change lots of code. It would not be possible to do this if foo_srv.log.dir appeared in application code. Instead, it is best for the two parts of a name to be specified separately, and then merged to form the fully-scoped name.

It would be tedious for developers to do such merging manually. To avoid this, the Config4J operations that work on scoped names take two string parameters. Internally, the operations merge the strings to obtain a fully-scoped name. For example, you can access the value of foo_srv.log.dir with the following statement:

logDir = cfg->lookupString("foo_srv", "log.dir");

The intention is that an application can declare a variable called, say, scope and initialize its value from a command-line argument. Then the application can access configuration information from within that scope by using code like that shown below:

logDir = cfg.lookupString(scope, "log.dir");

By rerunning an application with a different command-line argument, you can change the scope used to configure the application. This provides a lot of flexibility. For example, you might have one configuration scope for running an application without debugging diagnostics, and another scope that enables debugging diagnostics. Alternatively, you might have a separate scope for each instance of a replicated server application.

Unfortunately, I do not have a Java 1.3 compiler installed on my development machine. Instead, I compile Config4J with javac -source 1.3, which would complain if I tried to use newer language features. However, that is not a foolproof way to ensure compatibility with Java 1.3 because I might be accidentally using a class or operation that was introduced in a later version of Java.

Previous Up Next