Skip to content

picocli vs JCommander

Remko Popma edited this page Jun 8, 2018 · 46 revisions

How does picocli compare to JCommander?

JCommander is a great product and is one of the sources of inspiration for picocli. This page gives a quick overview of the differences between picocli and JCommander. The views below are my views, and as picocli’s author I am biased. I still hope this page is useful for people that are trying to decide which command line parsing library to use.

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.

  • Annotations API and programmatic API (since picocli v3). JCommander only offers annotations. The programmatic API is useful for dynamic applications where the options are discovered at runtime, useful for building a command-line DSL (domain-specific languages) and allows the use of picocli in JVM languages that don’t work well with annotations.

Parser Comparison

Picocli Parser 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.

  • 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.

Picocli is simpler than JCommander

  • 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) just work; no need to implement a IStringConverter<List> interface

  • Strongly typed Maps (not only Map<String, String>) just work; 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)

  • 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)