Friday, September 8, 2017

Java Command-Line Interfaces (Part 15): Jargo

Jargo is defined on its main GitHub page as "a tool to ease the handling of program arguments/options." That page provides a Rationale for another command line processing library when so many others already exist and the top of that list is, "Because type-safety, immutability and readability matters."

Jargo's options "definition" stage uses generic typed instances of the Argument class. These instances of Argument are created via static methods on the Arguments class to establish the type and then using builder-style methods to describe the option. This is demonstrated in the next screen snapshot which depicts definition of options for file path/name and verbosity (full code listing is available on GitHub).

"Definition" Stage with Jargo

final Argument<String> filePathAndName
   = stringArgument().description("Path and name of file.")
                     .names("--file", "-f")
// Use optionArgument() instead of booleanArgument() to avoid need
// to specify true or false as arguments to --verbose/-v option
final Argument<Boolean> verbose
   = optionArgument("--verbose", "-v")
                    .description("Enables verbosity.")
                    .names("--verbose", "-v")

The stringArgument() and optionArgument() methods shown above are called on the statically imported (not shown) Arguments class. The optionArgument() method needed to be used for the verbosity flag to avoid being required to explicitly state true or false after the verbosity flag.

The "parsing" stage is implemented with the class CommandLineParser and its fluent API methods as shown in the next code listing.

final ParsedArguments parsedArguments
   = CommandLineParser.withArguments(filePathAndName, verbose)

The instance of ParsedArguments provided by the CommandLineParser can be used for the "interrogation" stage. This is accomplished by invoking the "get" method on the ParsedArguments instance and passing it the appropriate Argument instance. The next code listing demonstrates this.

"Interrogation" Stage with Jargo

out.println("File path/name is '" + parsedArguments.get(filePathAndName)
   + "' and verbosity is set to '" + parsedArguments.get(verbose) + "'.");

The following screen snapshots depict use of Jargo. The first screen snapshot demonstrates the exception stack trace that occurs when a required option is not specified and the second screen snapshot demonstrates the long and short option names being used.

The stack trace shown in the first screen snapshot is not the nicest way to notify the user that a required option was not specified. Jargo allows a nicer message to be returned by catching the ArgumentException and calling its getMessageAndUsage() method. The code for this can be seen on GitHub and the results are shown in the next screen snapshot.

The screen snapshot demonstrates that the information provided in the instantiation of the Arguments is displayed. Jargo also allows an exception to be explicitly thrown to provide this information when a "help" argument is specified. This makes use of the static method helpArgument() on the Arguments class and an example of its usage is included in the GitHub code listing.

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

  • Jargo is open source and is licensed under the Apache License, Version 2.0.
  • Jargo's jargo-0.4.1.jar is approximately 177 KB in size, but it has a runtime dependency on the much larger Guava library.
    • The Guava dependency is an intentional decision as described in Jargo's Rationale: "Because I love Guava and wanted an argument parsing library well integrated with it (more to come in this department)."
    • This is obviously not an issue for the many applications that use Guava, but could be an issue for those wanting a command line processing Java-based library for a simple application that did not otherwise use Guava.
  • Jargo uses strongly typed API invocations to programmatically configure expected command line options rather than using annotations and/or reflection.
  • In a field with so many Java-based command line processing libraries available, Jargo is most likely to be a significant contender for a developer who desires all of the attributes of a command line processing library that Jargo's Rationale lists in explanation of why another library in this crowded space was developed.

Jargo is an easy to use library for processing command line options in Java and makes use of generic-typed classes and type-specific static methods to enforce type safety of command line options. Jargo requires Guava to run and so is best suited for applications already using Guava. A developer is likely to seriously consider Jargo over other alternate Java-based command line processing libraries if the items in the Jargo Rationale are all important to that developer.

Additional References

Wednesday, September 6, 2017

Java Command-Line Interfaces (Part 14): google-options

The GitHub page for google-options states that google-options is a "command line argument parsing library from the folks at Google (java)." The page goes on to say, "This is the command-line arguments parser from the Bazel Project. The package has been split out into a separate jar for general utility." This blog post demonstrates applying google-options to processing command line options from Java code.

The example used in this post to demonstrate google-options is similar to the examples used in the earlier thirteen posts in this series on processing command line options in Java. This example supports two options: a required file path/name option expecting a String argument with that path and name and a verbosity option with no argument (its existence enables verbosity). Only the most relevant portions of the code will be shown in this post, but the full code is available on GitHub.

The "definition" stage of Java-based command-line processing is accomplished in google-options via a custom class that extends google-options's class The custom class should provide public fields that correspond to the expected command line options and each of these public fields should be annotated with the @Option annotation. The @Option annotation requires two elements (name and defaultValue) and allows for optional elements such as help and abbrev. An example of this "definition" stage is provided in the next code listing for the custom Options class.

"Definition" Stage with google-options: Custom Options Class

 * Represents command-line options to be processed via
 * google-options library. Fields must be annotated with
 * @Option and must be public.
public class Options extends OptionsBase
           help="Path and name of file",
   public String filePathAndName;

           help="Enable verbose output",
   public boolean verbose;

The required "name" element of the @Option annotation specifies the "long" option name while the optional "abbrev" element specifies the "short" (single character) option name. The optional "help" element of the @Option annotation allows one to provide a "help" string for the option and the required "defaultValue" element specifies the default value for the option to be used when the option is not explicitly specified.

The "parsing" stage is accomplished in google-options by instantiating an instance of OptionsParser associated with the custom class with Option-annotated public fields and then invoking a "parse" method on that instance of OptionsParser. The next code listing demonstrates this with invocation of the OptionsParser.parseAndExitUponError(String[]) method.

"Parsing" Stage with google-options

final OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);

The "interrogation" stage with google-options is as simple as accessing the Option-annotated public fields on the custom class as demonstrated in the next code listing.

"Interrogation" Stage with google-options

     "Path/file name is '" + options.filePathAndName
   + "' and verbosity is '" + options.verbose + "'.");

The next code listing demonstrates how the OptionsParser method describeOptions can be used for displaying help details.

Using google-options's "Help"

private static void printUsage(OptionsParser parser)
   out.println("Usage: java Main <Options>");

The following screen snapshots demonstrate the above code listings. The first image depicts the "help" information provided when no arguments are provided and the second image depicts the two main command line options expressed in various long and short forms. One interesting observation that can be made from that second image is that google-options automatically supports a --noversion option for the boolean option explicitly specifying no verbosity.

The screen snapshots also demonstrate that google-options has a dependency on Guava.

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

  • google-options is an open source library licensed with the Apache License 2.0.
  • The google-options-1.0.0.jar is approximately 72 KB in size.
  • Applications using google-options also need to include Guava on the runtime classpath because google-options has a dependency on Guava. For applications using Guava anyway, this is not a big deal. However, for small applications not already using Guava, this may be more of a dependency than the application authors would like to have for a simple command-line based application.

Several of the Java-based command line processing libraries covered in this series use annotations to define the expected options and this is the approach used by google-options. Basic processing of command line options with google-options is a relatively straightforward process, but the cost of a new Guava dependency may be too high of a cost for simple applications that don't already depend on Guava.

Additional References

Saturday, August 26, 2017

Java Command-Line Interfaces (Part 13): JArgs

JArgs 1.0 has the distinction of being the subject of the 13th post of my series on parsing command line arguments in Java. JArgs is an open source (BSD license) library that has been primarily supported by different contributors including Steve Purcell and Ewan Mellor. It turns out that this can lead to some confusion when first using JArgs because package names and other details change depending on which version of JArgs you apply.

The JArgs project page describes JArgs as "a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers." The page asserts that JArgs might be selected over other Java-based command line processing libraries because JArgs is "easy to use, thoroughly tested, well documented and liberally licensed (BSD licence so no GNU messiness)." The page also states, "The package is small and without frills, but is functional, and contains code that has been in production use for quite some time."

JArgs is indeed small. The file is under 200 KB in size and the extracted core jargs.jar is only about 12 KB. There are no third-party library dependencies. The following screen snapshot demonstrates the contents of jargs.jar downloaded from SourceForge (the jargs-1.0.jar available on the Maven Repository is similar).

The documentation for JArgs consists primarily of its Javadoc-generated API documentation and code examples such as OptionTest and CustomOptionTest.

When using JArgs, the main class one uses is CmdLineParser (jargs.gnu.CmdLineParser or com.sanityinc.jargs.CmdLineParser depending on where you get your distribution of JArgs and which version you get). If using the JArgs JAR available via SourceForge download or via the Maven Repository, the primary class you'll be using is jargs.gnu.CmdLineParser. On the other hand, if you build JArgs from source available on GitHub (purcell/jargs), the main class will be com.sanityinc.jargs.CmdLineParser. In either case, there is just the one CmdLineParser outer class and it uses nested classes for additional support. In this post, I'm demonstrating examples based on the SourceForge/Maven JARs with jargs.gnu.CmdLineParser. The full source code of my examples will be posted on GitHub and that version will likely be edited to take advantage of more explicit imports for greater code conciseness and readability.

JArgs is small and so surprisingly is simple. It doesn't provide a lot of fancy features, but it does do basic command line argument processing with a simple programmatic approach that doesn't make use of annotations or reflection.

To implement the "definition" stage of command-line argument parsing with JArgs, one instantiates an instance of the CmdLineParser class and invokes the addOption(CmdLineParser.Option) method on that instance for each anticipated command line option. Each option is represented by an instance of a class that extends the CmdLineParser.Option class. In the examples in this series, I have been using a String-based file path/name option and a boolean-based verbosity option. So, when using JArgs for these examples, I can use the class CmdLineParser.Option.StringOption for file path and name and the class CmdLineParser.Option.BooleanOption for the verbosity option. The next code listing demonstrates implementation of the "definition" stage with JArgs.

"Definition" Stage with JArgs

public static void main(final String[] arguments)
   final CmdLineParser cmdLineParser = new CmdLineParser();
   final CmdLineParser.Option fileOption = new CmdLineParser.Option.StringOption('f', "file");
   final CmdLineParser.Option verbosityOption = new CmdLineParser.Option.BooleanOption('v', "verbose");

"Parsing" with JArgs requires just one statement, but you do need to catch the two checked exceptions thrown by the CmdLineParser.parse(String[]) method or explicitly state that these are thrown from your code that invokes with method. This is shown in the next code listing.

"Parsing" Stage with JArgs

catch (CmdLineParser.IllegalOptionValueException | CmdLineParser.UnknownOptionException exception)
   out.println("Unable to parse command line options - " + exception);

When the code just shown executes successfully (without throwing either of the two checked exceptions), the instance of CmdLineParser upon which the parse(String[]) method was invoked now contains the values parsed for the expected command-line options and so we're ready to "interrogate" that instance.

JArgs "interrogation" stage of command line options processing uses methods on the CmdLineParser.Option-extending classes discussed earlier to retrieve the values parsed for each of those options. There are overloaded versions of the CmdLineParser.getOptionValue() methods for performing this interrogation. The method accepting only the instance of Option whose value is desired [getOptionValue(CmdLineParser.Option)] returns null if the option wasn't found or parsed. The method accepting the instance of Option whose value is desired and a second "default" object [getOptionValue(CmdLineParser.Option, Object)] returns the provided default object if that option was not found or parsed. In the code listing below, I use the second form in both cases and thus ensure I don't have to deal with null.

"Interrogation" Stage with JArgs

final String filePathName = cmdLineParser.getOptionValue(fileOption, "null").toString();
if (filePathName.equals("null"))
   out.println("ERROR: File path/name must be provided.");
     "File path/name is " + filePathName
   + " and verbosity is " + cmdLineParser.getOptionValue(verbosityOption, false)
   + ".");

With these basic code examples in place, running the simple Java application that uses JArgs to command-line processing is demonstrated in the following screen snapshot.

The CmdLineParser class does not come with any built-in help/usage support. However, the available on SourceForge includes the source code for AutoHelpParser, a class which extends CmdLineParser and illustrates how help/usage could be implemented.

Because it's dated and due to its simplicity, JArgs can probably be used with older versions of Java than some of the other Java-basd command-line parsing libraries discussed in this series. When I run javap on CmdLineParser in the Maven-provided jargs-1.0.jar and the SourceForge-provided jargs.jar, to determine the version of Java it was compiled with, I see that it's major version 45! As I wrote in my post "Programmatically Determining Java Class's JDK Compilation Version", a major version of 45 indicates that the code was compiled with JDK 1.1!

Maven-provided jargs-1.0.jar Version Information from javap

Classfile jar:file:/C:/lib/jargs-1.0/lib/jargs-1.0.jar!/jargs/gnu/CmdLineParser.class
  Last modified Apr 9, 2005; size 6032 bytes
  MD5 checksum b2d61c0ce786f8a661cccf1e61de2a19
  Compiled from ""
public class jargs.gnu.CmdLineParser
  minor version: 3
  major version: 45

SourceForge-provided jargs.jar Version Information from javap

Classfile jar:file:/C:/lib/jargs-1.0/lib/jargs.jar!/jargs/gnu/CmdLineParser.class
  Last modified Apr 9, 2005; size 6032 bytes
  MD5 checksum b2d61c0ce786f8a661cccf1e61de2a19
  Compiled from ""
public class jargs.gnu.CmdLineParser
  minor version: 3
  major version: 45

Here are characteristics of JArgs to consider when selecting a framework or library to help with command-line parsing in Java.

  • JArgs is open source and is licensed with the BSD license.
  • There seems to be some confusion about versions and primary contributors to JArgs with Maven and SourceForge having one version and purcell/jargs on GitHub having another version.
  • JArgs is small and simple: the jargs.jar (or jargs-1.0.jar on Maven) is only about 12 KB in size and there are sno third-party library dependencies.
  • JArgs uses programmatic APIs for defining, parsing, and interrogating options rather than using annotations or reflection.
  • JArgs is a bit dated with many of its main pages having "latest updates" with years such as 2005. However, the GitHub page referenced in this post several times, and which has the different package name for its main class, shows its last updates being 2012.
  • I believe that JArgs could be used with the vast majority of Java applications today as it appears to me to be able to work with Java versions as far back as Java SE 1.1.

The most compelling reasons one might have to use JArgs instead of some of the other more commonly used and/or more recently updated Java-based command-line processing are its simplicity and small size. I sometimes face the decision of what level of command-line options I want to support JArgs provides a library that might be desirable when I want just a bit more than directly parsing the passed-in String[] to the main function, but don't want the power and complexity of some of the other Java-based command line processing libraries. My biggest concerns about using JArgs are probably that it hasn't been updated in a while and the potential confusion that could result for others using my work and having to deal with two different manifestations of JArgs with difference package name for its main class (using Maven for the dependency could help a lot here). JArgs is small and simple and might find its niche for those only desiring the most basic command line processing.

Additional References

Wednesday, August 23, 2017

Java Command-Line Interfaces (Part 12): CLAJR

The featured library for my twelfth post on processing command-line arguments in Java is Command-Line Arguments with Java Reflection (CLAJR). This "library" is a single Java source file ( available for download on SourceForge. The main page for CLAJR currently shows a 2006 copyright date and the downloadable source zip file is dated 6 December 2008. Although CLAJR appears to be largely unsupported in recent years and although it's unlikely that I'd choose CLAJR over some of the alternative libraries already discussed in this series for processing command line arguments from Java code, I believe CLAJR warrants a post focused on it. There are some fairly unique characteristics of CLAJR that make it interesting, even if one chooses not to use it.

CLAJR is not provided as a JAR. Instead, it's provided as a single zipped file with a single Java source code file contained in that ZIP file. Being available as a single source code file is not unique to CLAJR; Picocli also is provided in a single Java source code file. However, Picocli also makes a JAR available on the Maven repository (which I used when working with Picocli), but I'm not aware of a pre-built JAR with the appropriate .class files for CLAJR. Therefore, because I prefer a JAR over a source code file when using third-party libraries, the first thing I did when experimenting with CLAJR was to build its provided source code into a small JAR file.

Here are the steps I used to build a JAR with CLAJR (I had to make a slight change to the source file and that change is described later in this post):

  1. Download from SourceForge.
  2. Unzip to extract
  3. Create a directory clajr to represent the Java clajr package that the Java source class should exist within.
  4. Move the file to the clajr directory and rename it to match the name of the class inside that source file.
    • I also had to edit the source code to make a minor change; this is discussed in more detail later in the post.
  5. Use javac to compile the file into the multiple class files.
  6. Use jar to assembled the compiled .class files into a JAR (I named it CLAJR-0.9.jar).

The above steps are illustrated in the following two screen snapshots.

The Java-based command-line parsing libraries covered so far in this series tend to use annotations or specific programmatic APIs to allow for the definition, parsing, and interrogation of command-line arguments in Java code. CLAJR, as its full name suggests, instead uses Java reflection for defining the expected arguments to be parsed.

The main CLAJR page describes why the author chose reflection on methods' names for defining command-line arguments. CLAJR looks for methods that are named to correspond with the parameter or parameters being processed. A single underscore precedes a method name for a single-hyphen command-line argument while a double underscore precedes a method name for a double-hyphen command-line argument. A single method can be named to align with multiple command-line arguments when the multiple command-line arguments do the same thing.

As with the other posts in this series, my example for this post demonstrates use of the CLAJR library to model --file/-f command-line arguments and --verbose/-v command-line arguments. To "define" these in CLAJR, I need to name my methods _f__file and _v__verbose to correspond to -f/--file and -v/--verbose arguments. This is demonstrated in the partial snippet of a nested class Options in the next code listing.

"Definition" Stage in CLAJR: Reflection

 * Used reflectively by CLAJR to parse and interrogate command line
 * options defined as fields in this class.
public static class Options
   private String file;
   private boolean verbose;

   public void _v__verbose()
      verbose = true;

   public void _f__file(String newFilePathAndName)
      file = newFilePathAndName;

Parsing with CLAJR is a matter of a single statement. The next two lines of code demonstrate calling the static CLAJR.parse(String[], Object...) and passing to it the command-line arguments and just-instantiated instance of the Options class partially shown above.

"Parsing" Stage in CLAJR

final Options options = new Options();
CLAJR.parse(arguments, options);

In the single line parsing shown above, there is no return value from the parse method. Instead, the passed-in "options" instance has its fields populated according to which arguments are provided on the command line. CLAJR uses reflection on the "options" instance's methods to find the methods to invoke when corresponding arguments are discovered on the command line. It is this instance of Options that one can "interrogate" to find the values of arguments on the command line. This is demonstrated in the next code listing.

"Interrogation" Stage with CLAJR

out.println("File is '" + options.getFile() + "' and verbosity is set to '"
   + options.isVerbose() + "'.");

CLAJR supports providing of help/usage information on a per-method basis through reflection. In this case, methods are named with a convention similar to those for the command-line arguments themselves, but with help in front of the method name. This is demonstrated for the two combinations of arguments shown earlier in the next code listing.

CLAJR "Help" Methods

public String help_v__verbose()
   return "Enables verbosity of output.";

public String help_f__file()
   return "Path and name of file.";

The methods in the code listing just shown provide "help" strings for the -v/--verbose and -f/--file arguments. The static CLAJR method CLAJR.getHelp() method provides a String representing command-line usage that is based on these methods. CLAJR provides different exceptions that can be captured and these are often useful in conjunction with the "help" methods. These are demonstrated in the next code listing which shows the multiple catches that can be performed related to different error cases and other situations that warrant display of error information.

CLAJR's CLAJR.getHelp() and CLAJR Exceptions

catch (CLAJR.EmptyArgumentListException emptyArgsEx)
   out.println("Usage: Main -f|--file  [-v|--verbose]");
catch (CLAJR.HelpNeededException helpNeededEx)
catch (CLAJR.ParseException parseEx)
catch (Throwable throwable)  // CLAJR.parse throws Throwable

CLAJR 0.9's CLAJR.parse(String[], Object...) method throws a Throwable and so the code above catches that Throwable.

The three screen snapshots that follow demonstrate this simple example. The first image shows the usage printed when no argument is provided. The second image depicts a normal flow of defining, parsing, and interrogating command-line arguments. The third image demonstrates display of help information when an unexpected argument is provided on the command line.

To get my examples to work, I had to change the source file. Specifically, I changed line 491 in the invoke(String, String, boolean, List) method from if (tails == null) to if (tails == null || tails.isEmpty()). This is one of the advantages of open source; one can adjust or fix the code as necessary.

CLAJR allows a method named with a single underscore to be reflectively accessed. This - method corresponds to the "tail" parameter or parameters. I didn't use this in this example, but it's interesting to note that this will not work in JDK 9 because a single underscore is not allowed as an identifier in JDK 9. In fact, JDK 8's javac warns about this now as shown in the next screen snapshot.

Here are some additional characteristics of CLAJR to consider when selecting a framework or library to help with command-line parsing in Java.

  • CLAJR is open source and licensed with the GNU Lesser General Public License (version 2.1 or later).
  • CLAJR is available for download as an approximately 11 KB zip file called that contains the single file
  • CLAJR 0.9 does not require any third-party libraries to be downloaded.
  • CLAJR has been around for a while, but appears to not have been updated for several years. I had to make a minor change to the source code to get it to work properly for me.

CLAJR is a Java-based command-line processing library that is primarily distinguished from other libraries covered in this series by its use of reflection. Reflection is used to define expected command line arguments as well as the help messages associated with those arguments. CLAJR offers some unique ideas and approaches related to command-line processing in Java, but it's a somewhat dated library.

Additional Resources

Wednesday, August 9, 2017

Java Command-Line Interfaces (Part 11): CmdLn

This post describes using Ostermiller Java Utilities 1.08.02's CmdLn (Java Command Line Parser) to process command-line arguments from Java-based applications. The Ostermiller Java Utilities include several different types of utilities, but the focus of this post is on the "Command Line Parser" that is described on the components page, "Handle options and arguments to Java command line programs."

The Ostermiller Utilities command line parser does not use annotations, but instead employs the programmatic builder with fluent API concept that some of the other Java-based command-line parsing libraries have also used instead of annotations. The classes com.Ostermiller.util.CmdLn and com.Ostermiller.util.CmdLnOption are used together in the "definition" stage of command-line processing with CmdLn. This is demonstrated in the next code listing.

"Definition" Stage of CmdLn Processing

public static void main(final String[] arguments)
   final CmdLn cmdLn
      = new CmdLn(arguments).setDescription("Demonstrates CmdLn")
         .addOptions(new CmdLnOption[]{
            new CmdLnOption("help",'h'),
            new CmdLnOption("file",'f')
               .setArgumentBounds(1, 1)
               .setDescription("Path and name of file"),
            new CmdLnOption("verbose", 'v')
               .setArgumentBounds(0, 0)
               .setDescription("Enable verbosity")

In the just-shown code listing, three option are defined. One option is a "help" option and the other two options (-h/--help and -v/--verbose) are those used in the other posts in this series on command-line parsing in Java. The code demonstrates that a description can be set for each option for usage/help information and it is possible to designate whether each option is required or optional. The setArgumentBounds(int,int) method is used to specify the minimum and number of arguments that are expected for each option. The file option should always have one and only one argument (the file's path and name), so its minimum and maximum are both 1. The verbosity option should have no arguments (its presence means verbosity is enabled), so its minimum and maximum number of arguments are both 0.

The Ostermiller Java Utilities command line parser provides three approaches for "defining" what's to be parsed. The approach shown above is called the "Options by Name" approach on the CmdLn page. That pages also demonstrates defining the command line options to be parsed with the "Option Enum" and "Call Back to Listeners" approaches (not demonstrated in this post).

Normally in my posts on command-line parsing with Java-based libraries, I introduce how to implement the "parsing" stage after introducing how to implement the "definition" stage. However, with Ostermiller Utilities command line parser, the "parsing" stage is implicit and so I'll return to it after first covering the "interrogation" stage.

The "interrogation" stage is implemented by calling one of the overloaded getResult() methods on the CmdLn instance. If the overloaded getResult(-) method returns null, the option was not present (or not found during parsing). If that overloaded method returns a non-null value, that value will be of type CmdLnResult and represents a parsed option. That returned instance of CmdLnResult provides methods for accessing the argument or arguments associated with the option (such as accessing the path and file name of the -f/--file option in my example). This "interrogation" is demonstrated in the next code listing.

"Interrogation" Stage with CmdLn

if(cmdLn.getResult('h') != null)

String fileName = null;
if(cmdLn.getResult('f') != null)
   fileName = cmdLn.getResult('f').getArgument();
   out.println("Required parameter -f|--file not provided.\n" + cmdLn.getHelp());

boolean verbose = false;
if (cmdLn.getResult('v') != null)
   verbose = true;
out.println("File path/name is " + fileName + " and verbosity is set to " + verbose);

The CmdLn class also has getResults methods that return a List<CmdLnResult> to access multiple parsed options. The examples above demonstrate checking the results of the getResult() method call for null to determine whether an option is set or not. The full source code of the Java application used for this post is available on GitHub and uses CmdLn.present(char) instead of null checks for determining presence of an option. The differences can be seen here.

The Ostermiller Java Utilities command line parser does not require an explicit "parsing" call. Instead, the "interrogation" methods previously discussed (overloaded versions of getResult and getResults) implicitly parse when called. Each of these methods calls the public method CmdLn.parse(), but parsing actually only occurs on the first one called because the instance parses a boolean value that tells that instance it does not need to parse again on subsequent calls to getResult or getResults methods.

The next three screen snapshots demonstrate use of this simple Java application using Ostermiller Java Utilities command line parser. The first image depicts the output when no arguments (including the required file path/name argument) are specified. The second image depicts the help/usage output generated when the --help or -h option is specified and shows that there is no error message about the missing parameter in this case. The third screen snapshot demonstrates "happy path" execution of the simple application using the short and long forms of the file and verbosity options.

Here are some additional characteristics of Ostermiller Java Utilities CmdLn to consider when selecting a framework or library to help with command-line parsing in Java.

  • The Ostermiller Java Utilities that CmdLn is a part of are open source and the OstermillerUtils License is the GNU General Public License version 2 (GPL). The com.Ostermiller.util License FAQ explains why the GPL was chosen and the desire to avoid having these libraries "be used in closed source applications."
  • CmdLn is part of the greater Ostermiller Java Utilities, which is available as a single JAR. The ostermillerutils-1.08.02.jar is approximately 272 KB in size and no third-party JARs are needed (no other external dependencies).
  • The Ostermiller Java Utilities requires J2SE 5 or later.
  • The Ostermiller Java Utilities have not seen updates in recent years, but the Version History details the long-term availability of these utilities.

The command line parser portion of the Ostermiller Java Utilities is easy enough to use for basic command-line parsing and gets the job done. However, the Ostermiller Java Utilities have a more restrictive license than most of the open source Java-based command-line processing libraries discussed in this series. Also, one needs to include the entire Ostermiller Java Utilities JAR to get command-line processing functionality and that may feel a bit heavy for some simple command-line-driven applications. I believe that the command line parsing utility provided by Ostermiller Java Utilities will be most attractive to developers whose applications already use the Ostermiller Java Utilities for other utilities it provides.

Additional References

Monday, August 7, 2017

Java Command-Line Interfaces (Part 10): picocli

The main picocli page describes picocli as "a mighty tiny command line interface" that "is a one-file Java framework for parsing command line arguments and generating polished, easily tailored usage help messages. With colors." This post provides a brief overview of applying Picocli 0.9.7 to process command line arguments in Java code.

Like the other Java-based command line processing libraries covered in this series, picocli is open source. Because all of picocli's implementation exists in a single Java source code file, it's easy to use the source directly if desired. The picocli page emphasizes this, "A distinguishing feature of picocli is how it aims to let users run picocli-based applications without requiring picocli as an external dependency: all the source code lives in a single file, to encourage application authors to include it in source form." If you'd rather use picocli as a library, there is a JAR available on the Maven Repository with the numerous compiled .class files (Picocli features one Java file but with numerous nested classes and annotations).

The easiest approach for getting an idea of Picocli's single-file nature is to look at that single file itself. The Java source code for is available on the Picocli 'download' page. The next two screen snapshots show some output from javap when executed against the CommandLine class and when executed against one its inner annotations and one of its inner classes.

Whether one compiles into one's own class/JAR file or one chooses to use a pre-built JAR from Maven, the source code of an application using Picocli is obviously the same. The "definition" stage of parsing with Picocli is accomplished by annotating instance fields that will store values associated with command-line options. This is demonstrated in the code snippet below.

"Definition" Stage with Picocli

 * Demonstrate Java-based command-line processing with picocli.
   description="Demonstrating picocli",
   headerHeading="Demonstration Usage:%n%n")
public class Main
   @Option(names={"-v", "--verbose"}, description="Verbose output?")
   private boolean verbose;

   @Option(names={"-f", "--file"}, description="Path and name of file", required=true)
   private String fileName;

   @Option(names={"-h", "--help"}, description="Display help/usage.", help=true)
   boolean help;

The code sample just shown demonstrates that Picocli allows for multiple names of the option flags to be specified (I specified single-hyphen single-character names and double hyphen multi-character names in my example). The example also shows that required=true can be specified for required options and help=true can be specified for "help" options that support special help-specific behaviors such as printing usage details and avoiding errors related to absent required options. Note that Picocli 0.9.8 adds more specific help type support with versionHelp and usageHelp.

The "parsing" stage is accomplished in Picocli with CommandLine.populateCommand(T, String...), where the T is the instance of the class with Picocli-annotated fields and the remaining Strings are the arguments to be parsed. This is demonstrated in the next code snippet.

"Parsing" Stage with Picocli

final Main main = CommandLine.populateCommand(new Main(), arguments);

The "interrogation" stage with Picocli consists simply of accessing the Picocli-annotated fields of the instance passed to the CommandLine.populateCommand(T,String...) method in the "parsing" stage. A simple example of this "interrogation" is depicted in the next code listing.

"Interrogation" Stage with Picocli

     "The provided file path and name is " + main.fileName
   + " and verbosity is set to " + main.verbose);

To display help/usage information to the user when -h or --help is provided on the command line, it's as simple as "interrogating" the Picocli-annotated field that was designated help=true to see if that boolean is set or not and, if it is set, calling one of the overloaded CommandLine.usage methods. I happened to use one of the static versions of this method as shown in the next code listing.

Help/Usage with Picocli

if (
   CommandLine.usage(main, out, CommandLine.Help.Ansi.AUTO);

The next few screen snapshots demonstrate the simple Picocli-based processing application in action. The first image shows the type of error message and stack trace presented when a required flag is not present. The second image shows how the long and short names I specified in the annotations are respected. The third image shows the help feature in action.

One of Picocli's optional features that many of the other Java-based command-line parsing libraries don't have is color syntax support. The first code listing in this post showed some strings defined in annotations with @| |@ syntax. In the screen snapshot demonstrating "help" usage above, these characters were passed through as-is with no special treatment. However, if I instead run this sample code in Cygwin, I see what those tokens accomplish.

From the above screen snapshot, we see that Picocli applied some color syntax (yellow and white) automatically to the individual options' help and that it also applied the customized bold and underlined bold syntax to help description areas where the @| |@ syntax was applied.

Here are some additional characteristics of Picocli to consider when selecting a framework or library to help with command-line parsing in Java.

  • Picocli is open source and is licensed under the Apache License 2.0.
  • Picocli does not require any third-party libraries or frameworks to be downloaded.
    • Picocli source code is completely contained within a single .java file and that source can be copied and pasted into one's own configuration management system and built with the rest of the application code, meaning that even a Picocli JAR file is not strictly necessary.
  • The source code file (Picocli 0.9.7) is just under 3700 lines (including white space and comments) and is almost 200 KB in size. The picocli-0.9.7.jar file is approximately 83 KB in size.
  • Picocli enjoys current and frequent support. Its 0.9.8 version was released yesterday (after I had written most of this post).
  • Picocli documentation is detailed and in many ways more modern-feeling than the documentation for several other Java-based command-line processing libraries.
  • Picocli support for color syntax is easy to use and support for color syntax on different platforms is documented under the "Supported Platforms" section of the documentation.
  • Picocli's use of annotations on instance-level fields in similar to some of the other Java-based command-line processing libraries and enjoys the same advantages.
  • Basic Picocli features are highly approachable and easy to learn quickly, but Picocli also supports the ability to significantly customize several aspects of command-line processing with Picocli.

The code listings shown in this post are available in complete form on GitHub.

Picocli is a currently supported and updated library for processing command line arguments from Java. It features several of the newer features and approaches of some of the other available Java-based command-line processing libraries and throws in a couple differentiating features (color syntax and entire library encapsulated in single Java source file). Picocli is easy enough to use and appealing in its own right, but is most likely to separate itself from others in a particular developer's opinion if that developer desires the color syntax support or the ability to drop the source code file into the developer's project without any need for a JAR or compiled .class file.

Additional References

Monday, July 24, 2017

Java Command-Line Interfaces (Part 9): parse-cmd

The parse-cmd library consists of a single class,, that is "a Java-class used to define and parse command-line parameters in a Java application." The library is hosted on Google Code Archive and so could go away at any time. The JAR also appears to be available on GitHub. This post covers use of parse-cmd 0.0.93 to process command line arguments in Java.

The parse-cmd Requirement Wiki lists several alternatives for processing command line arguments in Java, including some which have been covered previously in this series. After listing these alternatives, it states, "Reviewing these and other entries, it was time to try another parser." The document then goes on to delineate requirements that parse-cmd seeks to satisfy.

The "definition" stage of parsing command-line arguments with parse-cmd is demonstrated in the next (incomplete) code listing. [Note that the example in this post is similar to that used in the previous eight posts in this series.]

"Definition" Stage with parse-cmd

/** String displayed where there is a problem processing arguments. */
private final static String USAGE =
   "java examples.dustin.commandline.parsecmd.Main --file <filePathAndName> [--verbose 1]";

public static void main(final String[] arguments)
   final ParseCmd parseCmd
      = new ParseCmd.Builder().parm("--file", "")
                              .parm("--verbose", "0")

The code listing demonstrates the definition of the expected command-line parameters using the ParseCmd.Builder() and the fluent methods available on instances of that class. Each method in turn returns an instance of the same Builder class so that these method calls can be chained together as shown above. As shown above, the usage/help string is built manually and provided to the Builder via the help(String) method rather than being built automatically by parse-cmd.

The parm method of the ParseCmd.Builder class is overloaded, but in this code listing I used the method parm(String, String) that accepts the name of the parameter and a "default" value for that parameter. Had I only provided one string to the method accepting just one string, the default would have been assumed to be "1" for that parameter. In the case of the file path and name argument, this can lead parse-cmd to assuming the wrong type of parameter. By providing an empty String explicitly as a default, parse-cmd is able to accurately treat the argument for file path and name as a variable-length string.

The --verbose argument is also defined in the above code and a default value is also provided to it because the implicit default of "1" would have turned verbosity "on" when no argument was provided and that's not been the default for verbosity in any of the earlier posts in this series of command-line parsing with Java.

The invocation of req() on one of the chained returned instances of Builder indicates that the previously defined argument (--file) is required. The other argument (--verbose) does not have this specified and so is implicitly defaulted to optional.

As far as I can tell, there's no easy approach with parse-cmd to specifying an alias or synonym for the defined command-line arguments. In other words, I don't see a way to tell parse-cmd that --file and -f are the same command-line argument. Therefore, I only use the "long" version with double hyphens in this example for both arguments --file and --verbose.

With the previous Java-based command-line parsing libraries covered in this series, the "parsing" stage immediately follows the "definition" stage. While it's possible to make this same transition with parse-cmd, the advertised and preferred approach is to implement the "validation" stage after the "definition" stage and before the "parsing" stage. This stage allows one to see if any errors were found during validation of the available command line arguments and is demonstrated in the next (incomplete) code listing.

"Validation" Stage with parse-cmd

final String errorString = parseCmd.validate(arguments);
if (!errorString.isEmpty())
   out.println("ERROR: " + errorString);

The code listing just shown demonstrates use of the ParseCmd.validate(String[]) method used to validate that the command-line arguments match those expected as defined in the "definition" stage. If there are any unexpected results, a non-empty String is returned. An empty String is considered a good thing and indicates "valid" command-line arguments.

With valid arguments, one can next move to "parsing" those command-line arguments as demonstrated in the next single-line code listing.

"Parsing" Stage with parse-cmd

final Map<String, String> parsedArguments = parseCmd.parse(arguments);

The result of the invocation of ParseCmd.parse(String[]) is a Java Map<String, String> of argument name to argument value.

The "interrogation" stage with parse-cmd is implemented by simply accessing the Map<String, String> returned by the parsing stage. One can query the map's keys by the argument name and the returned value is the value associated with that argument name. Note that the implication is that all arguments, even "boolean" arguments like --verbose, have a value associated with them rather than the presence or absence of the flag being the only required thing. In other words, --verbose must be followed by a value when expressed on the command line. The interrogation in this case of the two expected arguments is demonstrated in the next code listing.

"Interrogation" Stage with parse-cmd

final Map<String, String> parsedArguments = parseCmd.parse(arguments);
final String filePathAndName = parsedArguments.get("--file");
   out.println("The path/name of the file is '" + filePathAndName
      + "' and verbosity is set to '" + parsedArguments.get("--verbose") + "'.");

The full code listing for the example whose snippets have been shown in this post is available on GitHub.

The next screen snapshot demonstrates a message printed when a required command-line argument (--file) is not provided.

The screen snapshot that follows demonstrates successful application of the parse-cmd based command line processing of the --file and --verbose command line arguments.

Here are some additional characteristics of parse-cmd to consider when selecting a framework or library to help with command-line parsing in Java.

  • parse-cmd is open source with an Apache License 2.0.
  • parse-cmd is hosted on The Google Code Archive, which could be "turned down" at any time (currently states, "which will be turned down in early 2016").
  • The parsecmd-0.0.93.jar JAR file is approximately 50 KB in size.
  • parse-cmd employs a fluent Builder implementation instead of using annotations.

parse-cmd is another library (currently) available for Java developers who need to process command line arguments. It uses some assumptions and implications to make some of its decisions. The author of parse-cmd has written that parse-cmd was written despite "several Java-based command-line parsing solutions [being] available" because "they are generally complex to learn and use."

Additional References

Monday, July 17, 2017

Java Command-Line Interfaces (Part 8): Argparse4j

Argparse4j is a "Java command-line argument parser library" that its main page describes as "a command line argument parser library for Java based on Python's argparse module." In this post, I will look briefly at using Argparse4j 0.7.0 to process command-line arguments similar to those parsed in the seven earlier posts in this series on command-line processing in Java.

The arguments "definition" stage of command-line processing with Argparse4j can be accomplished via the ArgumentParser interface and its addArgument(String...) method. The return type of the addArgument(String...) method is an instance of the Argument interface. Implementations of that interface (usually ArgumentImpl) provide methods for setting the characteristics of each argument. Because each of these methods returns an instance of Argument, these calls can be chained together in a highly fluent manner. This is demonstrated in the next screen snapshot.

"Definition" Stage with Argparse4j

final ArgumentParser argumentParser =
   ArgumentParsers.newArgumentParser("Main", true);
argumentParser.addArgument("-f", "--file")
              .help("Path and name of file");
argumentParser.addArgument("-v", "--verbose")
              .help("Enable verbose output.");

In the above code listing, an instance of ArgumentParser is instantiated with a static initialization method that expects a String argument representing the script or program name that will be included in usage/help output. The second argument to the ArgumentParsers's newArgumentParse(String, boolean) method specifies that "help" options -h and --help will automatically be supported.

The first argument defined in the above code listing allows for a file path and name to be specified on the command line. The strings "-f" and "--file" are passed to the addArgument(String...) method, meaning that either -f or --file can be used on the command line to specify the file path and name. Three additional methods [dest(String), required(boolean), and help(String)] are called on the instances of Argument created as part of the specification of this first argument. These three methods respectively specify a name by which the argument can be referenced in the code, that the argument must be present on the command line, and the string to be displayed when help is requested for that argument.

The second argument defined in the above code listing passes the strings "-v" and "--verbose" to the addArgument(String...) method to allow this argument to be represented on the command line with either the short or long option name. Like the first argument, this one has the name it will be referenced by in the code set by the dest(String) method and has its string for "help" output specified with the help(String) method. This second argument is not required and so the required(boolean) method is unnecessary here.

The second argument's definition has a few additional methods on Argument called. I used type(Class<T>) to demonstrate the ability to explicitly specify the Java data type expected for the argument. I also needed to specify the combination of the nargs(String) and setConst(Object) methods to specify that the verbosity argument does not need a value provided with the flag. This allows me to specify -v or --verbose with no "true" or "false" after those options expected to be explicitly stated.

The "parsing" stage of command-line processing is supported in argparse4j with a call to the ArgumentParser's parseArgs(String[]) method. The next code listing demonstrates this.

"Parsing" Command Line Arguments with Argparse4j

final Namespace response = argumentParser.parseArgs(arguments);

Parsing requires only a single statement and returns an instance of Namespace.

The "interrogation" stage of command line processing with Argparse4j involves accessing the parsed command-line arguments from the Map that the Namespace instance wraps. The keys of this map are the strings specified with the dest(String) method and the values of the map are the values associated with those argument names. Interrogating these values is demonstrated in the next code listing.

"Interrogating" Command Line Arguments with Argparse4j

final String filePathAndName = response.getString("file");
final Boolean verbositySet = response.getBoolean("verbose");

     "Path/name of file is '" + filePathAndName
   + "' and verbosity is "
   + (Boolean.TRUE.equals(verbositySet) ? "SET" : "NOT SET")
   + ".");

In the just listed code, the keys of "file" and "verbose" were used because those same strings were provided with the dest(String) method when defining the expected arguments.

The full source code from which the code snippets above were extracted can be seen on GitHub.

The next screen snapshot demonstrates running the simple Java application without any arguments and the message that is displayed regarding the missing required "file" argument.

The all uppercase "FILE" shown in the above screen snapshot comes from the string that was specified in the dest(String) method when defining the expected argument. In other words, that dest(String) specification set both the string by which the argument mapping is keyed internally and the target string displayed in the help/usage.

The next screen snapshot demonstrates several variations of typical uses of the "file" and "verbose" options.

The final screen snapshot demonstrates that help information that is provided for -h or --help options because the original instance of ArgumentParser was created with the "addHelp" argument set to true.

Here are some additional characteristics of Argparse4j to consider when selecting a framework or library to help with command-line parsing in Java.

  • Argparse4j is open source and licensed with the MIT License.
  • The argparse4j-0.7.0.jar (December 2015) is approximately 89 KB in size and has no additional third-party library dependencies.
  • Argparse4j does not make use of annotations.
  • The online documentation includes a Clojure example.
  • I suspect that Java developers who write their scripts in Python (particularly if they use argparse) would experience advantages when using argparse4j in their Java applications that need to parse command-line arguments.
    • (I find Apache Commons CLI to be intuitive when processing command-line arguments in Java because I much more frequently parse command line arguments in Groovy than in Java and Groovy supplies built-in Apache Commons CLI support)
  • Argparse4j inspired the development of argparse4s for Scala.

Argparse4j is just one of many Java-based command line processing libraries. The characteristic of Argparse4j that most sets it apart from the numerous other options is its argparse heritage. Given that, I believe that the Java developers most likely to select Argparse4j for their Java command line processing needs would be those developers who frequently parse command line arguments in Python-based scripts and tools using argparse or who prefer command parsing semantics of Python and argparse.

Additional References

Monday, July 10, 2017

Java Command-Line Interfaces (Part 7): JCommander

This is the seventh post in my series that briefly introduces various libraries for processing command-line arguments in Java. This post returns to coverage of an annotation-based library that seems to be one of the better known and more popular of the numerous available libraries for processing command line arguments from Java: JCommander.

JCommander's web page states, "Because life is too short to parse command line parameters" and the Overview introduces JCommander as "a very small Java framework that makes it trivial to parse command line parameters." The code examples and associated screen snapshots of the executing code in this post are based on JCommander 1.72 (June 2017). The full code for the demonstrations shown here is available on GitHub.

JCommander uses annotations to implement the "definition" stage of command-line processing. This is demonstrated in the next code listing snippet.

"Definition" Stage with JCommander

 * Demonstrates use of JCommander for Java-based command-line processing.
public class Main
              description="Enable verbose logging")
   private boolean verbose;

              description="Path and name of file to use",
   private String file;

   @Parameter(names={"-h", "--help"},
   private boolean help;

   // . . .

final JCommander commander
   = JCommander.newBuilder()
              .programName("JCommander Demonstration")

The just-shown code listing demonstrates use of JCommander's @Parameter annotation to define the command-line options via annotation of class fields. The examples demonstrate specification of names to indicate multiple option flags to be associated with a single option, description to provide a description of each option, required=true to enforce presence of a command-line argument, and help=true to indicate a "help" or "usage" command-line argument (instructs JCommander to not throw exception if required arguments are not also provided).

With the class attributes annotated with @Parameter annotations, an instance of the class with annotated fields can be used to create an instance of the JCommander class. In the code example above, I took advantage of the JCommander.Builder for the greater fluency and other advantages associated with use of builders. In particular, the instance with annotated class fields is added via the addObject(Object) method.

The "parsing" stage of command-line processing with JCommander is accomplished via a single line invocation of the parse(String...) method on the instance of JCommander that was just instantiated. This is demonstrated in the next code listing.

"Parsing" Stage with JCommander


The "interrogation" stage of command-line processing with JCommander involves simply accessing the annotated fields of the instance passed to the JCommander class instantiation. This is demonstrated in the next code listing.

"Interrogation" Stage with JCommander

if (help)
      "The file name provided is '" + file + "' and verbosity is set to " + verbose);

The last code listing demonstrates the ability to determine if the boolean attribute with name help was set by the specification of --help or -h. Because it's a simple boolean, it can be used in the conditional and, if true, the help/usage information is presented. In the case when the "help" flag was not set, values associated with the other command line options ("verbose"/-v/--verbose and "file"/-f/--file) are accessed.

The most recent code listing also demonstrates writing the usage information to standard output via an invocation of the method usage() on the instance of the JCommander class. It's worth noting that ParameterException also has a usage() method.

The next series of screen snapshots demonstrate using JCommander with a simple application that includes the above code snippets. The first image shows running the JCommander-based application without any arguments and shows the ParameterException that is displayed in that case because the required --file/-f option was not specified.

The next screen snapshot demonstrates "normal" execution when the expected command line arguments are provided.

The next screen snapshot demonstrates use of the "help" option. Because this was annotated with help=true, the absence of the required "file" command-line argument does not lead to an exception and the automatically generated help/usage information is written to standard output.

JCommander provides a feature that I really like for developing with and learning JCommander. One can specify increased verbosity of the JCommander parsing by invoking the method verbose(int) on JCommandBuilder.

Increasing JCommander's Verbosity

final JCommander commander
   = JCommander.newBuilder()
               .programName("JCommander Demonstration")

With the increased verbosity, greater insight into what JCommander is doing related to command-line processing can be discovered and this is demonstrated in the following two screen snapshots.

Here are some additional characteristics of JCommander to consider when selecting a framework or library to help with command-line parsing in Java.

Additional References