Friday, September 29, 2017

Java Command-Line Interfaces (Part 17): jw-options

The JavaWorld article Processing command line arguments in Java: Case closed by Dr. Matthias Laux introduces a simple Java-based library for processing command-line arguments that I'll refer to in this post as jw-options. The referenced article provides background information on why certain design decisions were made in construction of the Options class. The "Conclusion" of the article describes the advantage of using the accompanying class and library: "This article describes a Java class that allows for the convenient processing of command line options for Java programs. The structure is flexible enough to handle even complex situations, while at the same time offering an API that allows for the definition of acceptable command line syntax with limited coding effort."

The "library" introduced by this JavaWorld article consists of three Java classes: Options, OptionData, and OptionSet. This is demonstrated in the following screen snapshot that displays the contents of options.jar.

The "definition" stage with "jw-options" is achieved with its Options and OptionSet classes. This is demonstrated in the next code listing (full code listing is available on GitHub and the example here is similar to those used in earlier posts in this series).

"Definition" Stage with jw-options

final Options options = new Options(arguments, Multiplicity.ZERO_OR_ONE);
final OptionSet defaultOptions = options.getSet();
defaultOptions.addOption("f", false, Separator.BLANK, Multiplicity.ONCE);
defaultOptions.addOption("v", Multiplicity.ZERO_OR_ONE);

The code listing just shown demonstrates using a couple of OptionSet's overloaded addOption methods. For setting up the option for file path and name (-f), a four-argument version is called with the single-letter of the flag ("f"), the separator between the flag and its argument (a space), and the number of times the flag should be expected (exactly one occurrence). The second argument for verbosity ("-v") is set up by calling the two-argument version of addOption that specifies the flag's character ("v") and its number of expected occurrences (zero occurrences or single occurrence).

The "parsing" stage is achieved in "jw-options" by invoking Options's check method. This method can also be used, as its name suggests, to check the accuracy of the arguments. This is demonstrated in the next code listing.

"Parsing" Stage with jw-options

if (!options.check(false, false))
{
   out.println("ERROR: " + options.getCheckErrors());
   System.exit(-1);
}

In the "parsing" example just shown, the Options class's method getCheckErrors() was used to access the errors in the parsed parameters that led to the Options.check method returning false.

The "interrogation" stage with "jw-options" is demonstrated in the next code listing.

"Interrogation" Stage with jw-options

out.println("File path/name is " + defaultOptions.getOption("f").getResultValue(0));
out.println("Verbosity is set to " + defaultOptions.isSet("v"));

The "interrogation" example demonstrates using OptionSet's getOption method to access the option representing the "-f" option and then calls its getResultValue(0) method to access the first (and only in this case) value associated with that "-f" flag. The second line in that example inquires simply whether the "-v" flag has been specified or not (and does not worry about or expect a value to be associated with that flag) via use of the OptionSet's method isSet.

A screen snapshot is shown next to demonstrate the code shown so far that uses "jw-options." The image shows the messages reported when expected command line arguments are not provided and ends with two examples using the command line flags as intended.

There are characteristics of "jw-options" to consider when selecting a framework or library to help with command-line parsing in Java.

  • The "jw-options" "library" is open source in the sense that it's source code is thoroughly introduced and discussed in the JavaWorld article "Processing command line arguments in Java: Case closed and the source code is included in the JAR available for download as the jw-0816-command.zip ZIP file." However, the license for this "library" is not obvious.
  • The "jw-options" library is small: the options.jar file is approximately 13 KB in size.
  • There is no third party library dependency for "jw-options."
  • As far as I can tell, there's no way to specify "long" flag names with double hyphens with "jw-options."
  • The javap command run on classes in the "jw-options" jar show "major version: 49", meaning that it's compiled against J2SE 5 and should work with applications running on Java as old as J2SE 5 (I noticed use of StringBuffer in the code where StringBuilder would have worked just as well).

The "jw-options" "library" discussed in this post is most likely to interest those who need to use a command line processing library with an older version of Java or who are interested in it in an academic sense. Because this "library" is described in detail in the associated JavaWorld article and because it's open source, one can peruse the code and review the article to see how it accomplishes the command line parsing and why it uses that approach. Given that the license for "jw-options" is not obvious and given that this is a relatively "old" library that doesn't seem to receive updates, it is likely that most Java developers would prefer some of the alternate libraries covered in this series over "jw-options" in many cases.

Additional References

No comments: