Skip to content

picocli vs JCommander

Remko Popma edited this page Sep 19, 2017 · 46 revisions

How does picocli compare to JCommander?

JCommander is a great product and is one of the sources of inspiration for picocli.

Unique in picocli

  • Picocli is designed to avoid becoming an external dependency. No other command line parser seems to have given this problem much thought.

  • Customizable usage help. Like many command line parsers, JCommander is focused on command line parsing, with a fixed usage help message. To customize the usage help in JCommander, one needs to programmatically build a custom help message using the ParameterDescription objects returned from the JCommander object in your application. By contrast, picocli provides annotations to easily customize common aspects of the usage help message. If the annotations are not sufficient, picocli provides a Help API for uncommon customizations.

  • Ansi colors and styles. Picocli usage help uses unobtrusive and easily customizable colors and styles where supported. Ships with a simple markup notation to allow application authors to colorize custom usage messages like headers, footers, description, etc.

  • Autocomplete. Picocli can generate a completion script for Bash and ZSH to autocomplete options and subcommands, for any level of subcommand depth.

Parser Comparison

Features

  • Positional parameters are 1st-class citizens in picocli: strong typing, arity and self-documented in the usage help message. JCommander effectively discourages positional parameters.

  • Support for clustered POSIX short options, so you can say <command> -xvfInputFile as well as <command> -x -v -f=InputFile, JCommander only supports the latter.

Simplified in picocli

  • Powerful and intuitive arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5". With JCommander one needs to choose between minimum arity or variable arity, and both are weakly typed - Strings only.

  • Converters can be registered on the CommandLine object; no need to implement a IStringConverterFactory interface

  • Arguments can be broken up by specifying a split regular expression; no need to implement a IParameterSplitter interface

  • Strongly typed collections (not only Lists) are easy: simply specify the type; no need to provide a special IStringConverters implementation for lists

  • Strongly typed Maps (not only Map<String, String>) are easy, simply specify key and value types; no need for a @DynamicParameter annotation

  • No IDefaultProvider, no IParameterValidator (I’m open to be convinced otherwise, but I just didn’t see how picocli interfaces would add more value than applications implementing a custom solution.)

Picocli Conveniences

  • Register nested subcommands via annotations or fluent API.

  • Fluent and compact API to minimize boilerplate client code.

  • Powerful parser tracing.

  • Many built-in type converters for commonly used types.

  • Works with Java 5 or higher (but is designed to facilitate the use of Java 8 lambdas). JCommander requires Java 8.

Some JCommander features not yet implemented in picocli (but on the todo list)

  • read command line arguments from a file

  • support for suppressing password echo to the console

  • case-insensitive option name matching

  • support for abbreviated options

  • internationalization

  • initializing custom objects from multiple command line arguments (equivalent to @SubParameter annotation)

  • reuse without subclassing (equivalent to @ParametersDelegate annotation)