Apache Commons CLI

A command-line argument processing library provided as part of the Apache Commons project.

javaclicommand-lineapacheargument-parsing

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());
        }
    }
}