Skip to content
Remko Popma edited this page Aug 17, 2017 · 38 revisions

Fearfully Anticipated Questions

What’s the big deal about the single source file?

How often have you chosen to write code to parse command line arguments instead of using a library because you didn’t want to burden your users with the extra dependency?

A library can be a great help, but it won’t make your users happy when they get a command line application and in order to run it they need to download and specify another jar file, especially when the only purpose of this library is to make life easier for the application author. End users need to do extra work to save the author some time? Not nice.

"Include as source (it’s only one file)" is one way to solve that problem. It is easy to understand, easy to do, and it doesn’t require any special tooling.

What’s wrong with shading jars?

That is another way to solve the problem. It requires some tooling, but it can certainly work. You have somewhat less visibility on what actually goes into the uberjar, and there are some times when shading can cause issues, but that’s usually when more libraries are combined.

However, including the source is simpler and avoids these issues.

That’s a pretty big source file. Is that maintainable?

Good point. There is always a trade-off. In this case, the trade-off is that it makes my work as a maintainer slightly harder, but makes things easier for the end user. That’s a good trade-off in my book.

Under the hood there are actually quite a few inner classes and interfaces, so it’s not as bad as you would think. The IDE does a good job here. We’ll see if it becomes a problem down the road, but if it does, it’ll be my problem and not the end user’s.

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. People have requested customizable help in JCommander for years but it’s not happening. 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.

Compared to JCommander:
  • 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)

  • An arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5" (JCommander only has minimum or variable arity, and these are weakly typed - Strings only)

  • Simplified:

    • a more intuitive arity model (see previous point)

    • 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

    • all Collections (not only Lists) just work, simply specify the type; no need for a listConverter attribute for special IStringConverters implementations

    • all Maps (not only Map<String, String>) just work, simply specify key and value types; no need for a @DynamicParameter annotation

    • no IDefaultProvider, no IParameterValidator: I just didn’t see much value in providing such picocli interfaces when applications can implement a custom solution that is just as (or more) fit for purpose, but I’m open to be convinced otherwise.

  • Fluent and compact API to minimize boilerplate client code.

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

  • reuse without subclassing (equivalent to @ParametersDelegate annotation)

How does picocli compare to other commandline parsers?

Please see the CLI comparison page for a detailed comparison.

Aren’t you just reinventing the wheel?

But I love wheels!

AAEAAQAAAAAAAARIAAAAJDRlMzk3Y2Y0LWQ0OTktNDU1Yi05MDk0LTJiYTVhODE0ODZjNA