Apache Commons CLI
A command-line argument processing library provided as part of the Apache Commons project.
Framework
Apache Commons CLI
Overview
Apache Commons CLI is a mature command-line argument processing library provided as part of the Apache Commons project. Developed and maintained by the Apache Software Foundation, it offers high reliability in enterprise environments and is used by many Apache projects. With its rich features and flexible design, it can handle everything from simple CLIs to complex command structures.
Why Apache Commons CLI is chosen:
- Enterprise Reliability: High reliability backed by the Apache brand
- Maturity: Over 20 years of development and operational experience
- Rich Features: Various option formats and validation capabilities
- Flexibility: Supports simple to complex CLI applications
- Standardization: Standard adoption across Apache project ecosystem
Details
History and Development
Apache Commons CLI development began around 2002 and has evolved as an important component of the Apache Commons project. It has been adopted by many Apache projects including Apache Maven, Apache Ant, and Apache Tomcat, making it a standard choice in enterprise Java development.
Position in the Ecosystem
- Apache Ecosystem: Adopted by Maven, Ant, Tomcat, and others
- Enterprise: Standard library in large corporations
- Community: Extensive documentation and community support
Key Features
Core Capabilities
- Multiple Option Formats: Short options (-h), long options (--help), GNU-style
- Argument Validation: Type checking and value validation
- Option Groups: Mutually exclusive and required option groups
- Flexible Parsing: Various parsing strategies and modes
- Help Generation: Automatic help message generation
Advanced Features
- Properties Integration: Integration with Java Properties
- Custom Types: Support for custom argument types
- Localization: Multi-language support
- Builder Pattern: Fluent API for option definition
Pros and Cons
Pros
- Proven reliability in enterprise environments
- Extensive feature set for complex CLI requirements
- Strong Apache community support and documentation
- Integration with other Apache Commons libraries
- Backward compatibility and stable API
- Comprehensive validation and error handling
Cons
- More verbose API compared to modern alternatives
- Learning curve for complex features
- Larger dependency footprint
- Less modern compared to annotation-based alternatives
Key Links
Usage Examples
Basic Option Definition
import org.apache.commons.cli.*;
public class BasicExample {
public static void main(String[] args) {
Options options = new Options();
// Add options
options.addOption("h", "help", false, "display help message");
options.addOption("v", "verbose", false, "enable verbose output");
options.addOption("f", "file", true, "input file");
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("myapp", options);
return;
}
if (cmd.hasOption("v")) {
System.out.println("Verbose mode enabled");
}
if (cmd.hasOption("f")) {
String filename = cmd.getOptionValue("f");
System.out.println("Processing file: " + filename);
}
} catch (ParseException e) {
System.err.println("Error parsing command line: " + e.getMessage());
}
}
}
Advanced Configuration with Builder
import org.apache.commons.cli.*;
public class AdvancedExample {
public static void main(String[] args) {
Options options = new Options();
// Using Option.builder for more control
Option input = Option.builder("i")
.longOpt("input")
.hasArg()
.argName("FILE")
.desc("input file to process")
.required()
.build();
Option output = Option.builder("o")
.longOpt("output")
.hasArg()
.argName("FILE")
.desc("output file")
.build();
Option format = Option.builder("f")
.longOpt("format")
.hasArg()
.argName("FORMAT")
.desc("output format (json, xml, csv)")
.build();
Option count = Option.builder("c")
.longOpt("count")
.hasArg()
.type(Number.class)
.desc("number of items to process")
.build();
options.addOption(input);
options.addOption(output);
options.addOption(format);
options.addOption(count);
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
String inputFile = cmd.getOptionValue("i");
String outputFile = cmd.getOptionValue("o", "output.txt");
String formatType = cmd.getOptionValue("f", "json");
if (cmd.hasOption("c")) {
Number countValue = (Number) cmd.getParsedOptionValue("c");
System.out.println("Processing " + countValue + " items");
}
System.out.println("Input: " + inputFile);
System.out.println("Output: " + outputFile);
System.out.println("Format: " + formatType);
} catch (ParseException e) {
System.err.println("Error: " + e.getMessage());
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("advanced-app", options);
}
}
}
Option Groups and Validation
import org.apache.commons.cli.*;
public class OptionGroupExample {
public static void main(String[] args) {
Options options = new Options();
// Create mutually exclusive options
OptionGroup group = new OptionGroup();
group.addOption(new Option("c", "create", false, "create new file"));
group.addOption(new Option("u", "update", false, "update existing file"));
group.addOption(new Option("d", "delete", false, "delete file"));
group.setRequired(true); // At least one option from group is required
options.addOptionGroup(group);
options.addOption("f", "file", true, "target file");
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
String operation;
if (cmd.hasOption("c")) {
operation = "create";
} else if (cmd.hasOption("u")) {
operation = "update";
} else if (cmd.hasOption("d")) {
operation = "delete";
} else {
operation = "unknown";
}
String filename = cmd.getOptionValue("f");
System.out.println("Operation: " + operation);
System.out.println("File: " + filename);
} catch (ParseException e) {
System.err.println("Error: " + e.getMessage());
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("file-manager", options);
}
}
}
Properties Integration
import org.apache.commons.cli.*;
import java.util.Properties;
public class PropertiesExample {
public static void main(String[] args) {
Options options = new Options();
options.addOption("D", "property", true, "system property");
options.addOption("f", "file", true, "input file");
options.addOption("v", "verbose", false, "verbose output");
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
// Handle properties (-D key=value)
Properties properties = cmd.getOptionProperties("D");
for (String key : properties.stringPropertyNames()) {
System.setProperty(key, properties.getProperty(key));
System.out.println("Set property: " + key + "=" + properties.getProperty(key));
}
if (cmd.hasOption("f")) {
String filename = cmd.getOptionValue("f");
System.out.println("Processing file: " + filename);
}
if (cmd.hasOption("v")) {
System.out.println("Verbose mode enabled");
}
} catch (ParseException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Custom Help Formatting
import org.apache.commons.cli.*;
public class CustomHelpExample {
public static void main(String[] args) {
Options options = new Options();
options.addOption(Option.builder("h")
.longOpt("help")
.desc("show help message")
.build());
options.addOption(Option.builder("i")
.longOpt("input")
.hasArg()
.argName("FILE")
.desc("input file to process")
.required()
.build());
options.addOption(Option.builder("o")
.longOpt("output")
.hasArg()
.argName("DIR")
.desc("output directory")
.build());
options.addOption(Option.builder("f")
.longOpt("format")
.hasArg()
.argName("FORMAT")
.desc("output format: json, xml, csv")
.build());
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(100);
formatter.setLeftPadding(2);
formatter.setDescPadding(2);
String header = "\nData Processing Tool\n\n";
String footer = "\nExamples:\n" +
" java MyApp -i data.txt -o output/ -f json\n" +
" java MyApp --input data.csv --format xml\n\n" +
"For more information, visit: https://example.com\n";
formatter.printHelp("myapp", header, options, footer, true);
return;
}
// Process other options...
} catch (ParseException e) {
System.err.println("Error: " + e.getMessage());
}
}
}