Lesson 48 • Expert

    CLI Tools with Java

    Build professional command-line tools using picocli — argument parsing, subcommands, and native images.

    Before You Start

    You should know IO & NIO (file operations), Exception Handling (error reporting), and Deployment (JAR packaging). Familiarity with Annotations helps since picocli is annotation-driven.

    What You'll Learn

    • ✅ Parsing command-line arguments manually and with picocli
    • ✅ Options, positional parameters, and type conversion
    • ✅ Subcommands and nested command hierarchies
    • ✅ ANSI colors, progress bars, and interactive prompts
    • ✅ Input validation and meaningful error messages
    • ✅ GraalVM native-image for instant startup

    1️⃣ Why picocli?

    Analogy: Parsing command-line arguments manually is like building a house from raw lumber — you can do it, but why? picocli is like a pre-fab kit: define your options with annotations, and picocli handles parsing, validation, help text, tab completion, and colored output automatically.

    ApproachLines of CodeFeaturesMaintenance
    Manual args[]100+ linesBasic parsing onlyHigh (all edge cases on you)
    Apache Commons CLI30-50 linesOptions, help textMedium (older API)
    picocli10-20 linesEverything + colors + completionLow (annotation-driven)

    Try It: Argument Parser Simulator

    Try it Yourself »
    JavaScript
    // 💡 Try modifying this code and see what happens!
    // CLI Argument Parser
    console.log("=== CLI Argument Parsing ===\n");
    
    // 1. Manual parsing (the hard way)
    console.log("1. MANUAL PARSING (Don't do this in production!):");
    function parseArgs(args) {
      let result = { options: {}, positional: [] };
      for (let i = 0; i < args.length; i++) {
        if (args[i].startsWith("--")) {
          let key = args[i].substring(2);
          let hasValue = args[i + 1] && !args[i + 1].startsWith("-");
          result.optio
    ...

    Try It: Subcommands & CLI Simulation

    Try it Yourself »
    JavaScript
    // 💡 Try modifying this code and see what happens!
    // Subcommands and interactive CLI
    console.log("=== Subcommands & CLI Execution ===\n");
    
    // 1. Subcommand hierarchy
    console.log("1. SUBCOMMAND HIERARCHY (like git):");
    console.log(`  @Command(name = "mytool", subcommands = {
          UserCommand.class,
          ConfigCommand.class
      })
      class MyTool implements Runnable { ... }
    
      @Command(name = "user", subcommands = {
          UserCreateCommand.class,
          UserListCommand.class,
          UserDeleteComm
    ...

    Try It: ANSI Colors & GraalVM Native

    Try it Yourself »
    JavaScript
    // 💡 Try modifying this code and see what happens!
    // ANSI output and GraalVM native compilation
    console.log("=== ANSI Colors & Native Images ===\n");
    
    // 1. ANSI color output
    console.log("1. ANSI COLORS IN CLI:");
    console.log(`  // picocli supports ANSI markup
      System.out.println(CommandLine.Help.Ansi.AUTO.string(
          "@|bold,green ✅ Success!|@ File processed."));
      System.out.println(CommandLine.Help.Ansi.AUTO.string(
          "@|bold,red ❌ Error:|@ File not found."));
      System.out.println(Co
    ...

    Common Beginner Mistakes

    • Not providing --help — users expect it. picocli's mixinStandardHelpOptions = true adds it automatically
    • Printing errors to stdout — errors go to System.err, normal output to System.out. This allows users to redirect output properly
    • Ignoring exit codes — scripts depend on exit codes. Return 0 for success, non-zero for errors
    • Hardcoding file paths — use @Parameters for file arguments. Support stdin with - as a conventional filename
    • No input validation messages — picocli validates types automatically, but add custom validation with clear error messages for business rules

    Pro Tips

    • 💡 Tab completion — picocli generates bash/zsh completion scripts with AutoComplete.bash("mytool", new MyTool()). Huge UX improvement!
    • 💡 Config file + CLI args — use @PropertiesDefaultProvider to load defaults from a config file, overridable by CLI args
    • 💡 Interactive mode — picocli supports @Option(interactive = true) for passwords. Prompts the user and hides input
    • 💡 man pages — picocli can generate AsciiDoc man pages from your annotated commands. Professional documentation for free!

    📋 Quick Reference

    Featurepicocli AnnotationExample
    Named option@Option(names = {"-n", "--name"})--name Alice
    Positional arg@Parameters(index = "0")file.txt
    Subcommand@Command(subcommands = ...)git commit
    Default valuedefaultValue = "10"Fallback if not provided
    Password@Option(interactive = true)Hidden input prompt
    CompletionAutoComplete.bash()Tab completion script

    🎉 Lesson Complete!

    You can now build professional CLI tools with picocli! You understand options, subcommands, ANSI output, and GraalVM native compilation. Next: Clean Architecture — designing maintainable, testable applications with SOLID and DDD.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service