Dustin's Pages

Monday, November 10, 2008

Command-line Parsing with Apache Commons CLI

From time to time, I find myself needing to handle command-line arguments in Java either for Java-based applications or for main() function implementations that provide a simple testing mechanism directly within the class being tested. The Java developer has many choices for command-line parsing. When there is only one, two, or a small number of command-line arguments (especially if the presence or absence of a flag is all that is needed rather than an accompanying value), writing a few lines of code to process these command-line options is not a big deal. When there are more options and/or some options have values, it is nice to access more sophisticated support for command-line parsing.

Before moving onto demonstrating CLI's parsing of command-line arguments based on these anticipated options, it is worth noting CLI's support for usage information and help information via the org.apache.commons.cli.HelpFormatter class. This useful utility class contains methods such as overloaded versions of printHelp, overloaded versions of printUsage, and several other output and related methods.

The following code snippet demonstrates a method that makes use of one of HelpFormatter's printUsage methods and one of that class's printHelp methods.

The first screen snapshot shows the results when the code above is executed exactly as shown (with true passed to both uses of the printHelp method to indicate that options should be included in the usage portion). The second screen snapshot shows what happens when the second call to printHelp has false passed to it so that the options are not displayed.

printUsage and printHelp

printUsage and printHelp with One printHelp Not Displaying Options

While the usage and help information about the options is, as their names imply, helpful and useful, the real reason for using command-line arguments is usually to control the behavior of the application. The next code listing shows two methods for parsing GNU-style and Posix-style command-line arguments. While the setting up of the Options did not care about the specific style other than specifying the options themselves, the type of option is important now for determining the appropriate parser to use.

One of the most significant drawbacks of Apache Commons CLI is the CLI version paradox advertised on the CLI's main page. This main CLI page points out that "the 2.x design is generally preferred" while also pointing out that, because there is no planned 2.0 release, "the 1.1 release is recommended to most users." I used CLI 1.1 for the examples in this blog entry.

Today I'm trying to use Apache Commons CLI in order to refactor some command line argument handling in a standalone application. But it seems to me that this library is not satisfactory because of some difficult api nomenclature and because (it seems to me) does not exists a way to install a custom type parser. I see that there exists a TypeHandler with an unnerving comment and reading the source code it's simply terrifying(for example there exists a date parser template method that ignores the dateformat...). I decided to not use this library in production. May be we have to wait for the next release.