Overview
When developing Java application for command line interface (CLI), it’s essential to parse input argument correctly. However, you don’t want to reinvent the wheel because it’s not easy and you’ve more important tasks to do, right? In my own experience, I found Apache Commons CLI very useful. I used it when maintaining nuxeoctl, and when I developing command line tools for side-projects.
Today, I would like to introduce Apache Commons CLI to you. After reading this article, you will understand:
- Prerequisite
- How to create “options”
- How to create individual “option”
- How to parse command line arguments
- How to query the parsed result
- How to show usage and help
Prerequisite
If you want to use Apache Commons CLI in your Java project, you need to declared the following dependency in Maven:
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
Or in Gradle:
commons-cli:commons-cli:1.4
Create Options
“Options” is the main entry-point of the library. “Options” represents a collection of “Option” objects, which describe the possible options for a command-line. It may flexibly parse long and short options, with or without values. Additionally, it may parse only a portion of a command line, allowing for flexible multi-stage parsing.
Options options = new Options();
Once done, you can add one or several new “Option” into “Options”, and parse “Options” afterwards.
Create Individual Option
“Option” describes a single command-line option. It maintains different information such as its short name, its long name, argument requirement, description etc. There are two ways to create a new option: via an instance of “Options”, or via option builder.
Create option via “Options”. Class org.apache.commons.cli.Options
provides
different methods for creating a new option. Here are some of the examples:
// Create an option with short name
// "-v" for enabling the verbose mode.
options.addOption("v", "Enable verbose mode");
// Create an option with short name
// "-f" for configuring filepath. It
// has an argument (hasArg=true).
options.addOption("f", true, "Config filepath");
// Create an option with short name
// "-i" or long name "--ignore", for
// specifying the case-sensitive case.
options.addOption("i", "ignore", false, "Ignore case");
Create option via builder. Class
org.apache.commons.cli.Option.Builder
can also be used to create an “Option”
using descriptive methods.
Option opt = Option.builder("a")
.longOpt("all")
.desc("Display all")
.build();
options.addOption(opt);
Parse Command Lines
Parsing command lines can be done by using CommandLineParser
and an instance
of “Options”. If the arguments are parsed successfully, the method will return
an instance of “CommandLine”. Else, it will throw a checked exception.
public static void main(String[] args) {
Options options = ...;
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
} catch (ParseException e) {
// ...
}
}
Query Command Line
Once you successfully created the command line instance, you can query it: to see if an option has been passed, or to retrieve the option value.
Query if the option exist:
if (cmd.hasOption("v")) {
// enable verbose mode...
}
If exists, return the option value. Note that, if the option does not exist, the
return value will be null
. Be careful about NullPointerException…
if (cmd.hasOption("f")) {
String path = cmd.getOptionValue("f");
// return null if the option does not
// exist in command line
}
If your application support default value, you can give it to the method as the 2nd parameter:
String e = cmd.getOptionValue("encoding", "utf-8");
Print Usage and Help
Use HelpFormatter
to generate the help with usage. The layout of the help
message looks like this:
header
-----
body (options)
-----
footer
By default, the header is the command line syntax, provided by user. The body is generated by the library. The footer is ignored.
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("cmd", newOptions());
usage: cmd
-a,--all Display all
-f <arg> Config filepath
-i,--ignore Ignore case
-v Enable verbose mode
However, you can enable the auto-usage for header, so that the options generated and included in header.
formatter.printHelp("cmd", newOptions(), true);
usage: cmd [-a] [-f <arg>] [-i] [-v]
-a,--all Display all
-f <arg> Config filepath
-i,--ignore Ignore case
-v Enable verbose mode
Conclusion
In this article, we see how to create “Options” and “Option” in Apache Command
CLI, how to parse “Options” using parser and exception handling, how to query
the result (CommandLine
), and print help and usage. The source code is
available at
mincong-h:blog/2019-08-06-cli,
under directory “cli”. Hope you enjoy this article, see you the next time!
References
- Apache, “Common CLI - Home”, Apache Commons, 2019. https://commons.apache.org/proper/commons-cli/index.html
- Apache, “Commons CLI - Javadoc”, Apache Commons, 2019. https://commons.apache.org/proper/commons-cli/apidocs/org/apache/commons/cli/package-summary.html
- Nuxeo, “nuxeoctl and Control Panel Usage”, Nuxeo, 2019. https://doc.nuxeo.com/nxdoc/nuxeoctl-and-control-panel-usage/