Jcommander Example

0 views
Skip to first unread message

Sandee Embree

unread,
Aug 5, 2024, 3:07:31 AM8/5/24
to birsgarcalis
Infact, JCommander provides a rather comprehensive set of built-in conversions for commonly used special types, just to name the most notable ones (list is incomplete): char[], File, Path, URI, URL, InetAddress, Date (ISO 8601), ByteOrder, Charset.

If one of your parameters is a password or some other value that you do not wish to appear in your history or in clear, you can declare it of type password and JCommander will then ask you to enter it in the console:


In Java 6, by default, you will not be able to see what you type for passwords entered at the prompt (Java 5 and lower will always show the password). However, you can override this by setting echoInput to true (default is false and this setting only has an effect when password is true):


By default, JCommander parses the command line into basic types only (strings, booleans, integers and longs). Very often, your application actually needs more complex types (such as files, host names, lists, etc.). To achieve this, you can write a type converter by implementing the following interface:


After parsing your parameters with JCommander, you might want to perform additional validation across these parameters, such as making sure that two mutually exclusive parameters are not both specified.


So far, all the @Parameter annotations we have seen had defined an attribute called names. You can define one (and at most one) parameter without any such attribute. This parameter can be either a List or a single field(for example a String or a type that has a converter, e.g. File), in which case there needs to be exactly one main parameter.


JCommander#setAllowAbbreviatedOptions(boolean): specify whether users can pass abbreviated options. If you call this method with true then users can pass "-par" to specify an option called -param. JCommander will throw a ParameterException if the abbreviated name is ambiguous.


For more complicated cases, you might want to be able to reuse identical default values across several main classes or be able to specify these default values in a centralized location such as a .properties or an XML file. In this case, you can use an IDefaultProvider:


By passing an implementation of this interface to your JCommander object, you can now control which default value will be used for your options. Note that the value returned by this method will then be passed to a string converter, if any is applicable, thereby allowing you to specify default values for any types you need.


For the most common cases, there is no need to actually implement IDefaultProvider, as JCommander contains the classes PropertyFileDefaultProvider and EnvironmentVariableDefaultProvider for reading defaults from a property file (jcommander.properties by default) or from an environment variable (JCOMMANDER_OPTS by default).


Then you register these commands with your JCommander object. After the parsing phase, you call getParsedCommand() on your JCommander object, and based on the command that is returned, you know which arg object to inspect (you can still use a main arg object if you want to support options before the first command appears on the command line):


Whenever JCommander detects an error, it will throw a ParameterException. Note that this is a Runtime Exception, since your application is probably not initialized correctly at this point. Also, ParameterException contains theJCommander instance and you can also invoke usage() on it if you need to display some help.


You can internationalize the descriptions of your parameters. First you use the @Parameters annotation at the top of your class to define the name of your message bundle, and then you use the descriptionKey attribute instead of description on all the @Parameters that require translations. This descriptionKey is the key to the string into your message bundle:


If you are writing many different tools in the same project, you will probably find that most of these tools can share configurations. While you can use inheritance with your objects to avoid repeating this code, the restriction to single inheritance of implementation might limit your flexibility. To address this problem, JCommander supports parameter delegates.


The example above specifies a delegate parameter Delegate which is then referenced in MainParams. You only need to add a MainParams object to yourJCommander configuration in order to use the delegate:


JCommander allows you to specify parameters that are not known at compile time, such as -Da=b -Dc=d. Such parameters are specified with the @DynamicParameter annotation and must be of type Map. Dynamic parameters are allowed to appear multiple times on the command line:


Picocli is a one-file framework for creating Java command line applications with almost zero code.It supports a variety of command line syntax styles including POSIX, GNU, MS-DOS and more. It generates highly customizable usage help messages that use ANSI colors and styles to contrast important elements and reduce the cognitive load on the user.


Picocli-based applications can have command line TAB completion showing available options, option parameters and subcommands, for any level of nested subcommands.Picocli-based applications can be ahead-of-time compiled to a native image, with extremely fast startup time and lower memory requirements, which can be distributed as a single executable file.


Another distinguishing feature of picocli is how it aims to let users run picocli-based applications without requiring picocli as an external dependency:all the source code lives in a single file, to encourage application authors to include it in source form.


Implement Runnable or Callable and your command can be executed in one line of code.The example main method calls CommandLine.execute to parse the command line, handle errors, handle requests for usage and version help, and invoke the business logic. Applications can call System.exit with the returned exit code to signal success or failure to their caller.


Compile time error checking. The annotation processor shows errors for invalid annotations and attributes immediately when you compile, instead of during testing at runtime, resulting in shorter feedback cycles.


GraalVM native images. The annotation processor generates and updates GraalVM configuration files underMETA-INF/native-image/picocli-generated/$project during compilation, to be included in the application jar.This includes configuration files for reflection, resources and dynamic proxies.By embedding these configuration files, your jar is instantly Graal-enabled.In most cases no further configuration is needed when generating a native image.


The picocli annotation processor supports a number of options, most important of which is the project option to control the output subdirectory: the generated files are written to META-INF/native-image/picocli-generated/$project. A good convention is to use the Maven $project.groupId/$project.artifactId as the value; a unique subdirectory ensures your jar can be shaded with other jars that may also contain generated configuration files.


There are many ways to run picocli-based applications, depending on whether we included picocli as source, created a jar for our application or not, and whether we created a shaded jar (also known as uber-jar) containing all dependencies.


Picocli 3.5 introduced password support: for options and positional parameters marked as interactive, the user is prompted to enter a value on the console.When running on Java 6 or higher, picocli will use the Console.readPassword API so that user input is not echoed to the console.


The example below demonstrates how an interactive option can be used to specify a password.From picocli 3.9.6, interactive options can use type char[] instead of String, to allow applications to null out the array after use so that sensitive information is no longer resident in memory.


When running on Java 6 or higher, the user input is not echoed to the console.After the user enters a password value and presses enter, the call() method is invoked, which prints something like the following:


Interactive options by default cause the application to wait for input on stdin. For commands that need to be run interactively as well as in batch mode, it is useful if the option can optionally consume an argument from the command line.


The default arity for interactive options is zero, meaning that the option takes no parameters. From picocli 3.9.6, interactive options can also take a value from the command line if configured with arity = "0..1". (See Optional Values.)


However, if the password is not specified, the user will be prompted to enter a value. In the following example, the password option has no parameter, so the user will be prompted to type in a value on the console:


A command that combines either of these with an interactive --password option (with the default arity = "0") allows end users to provide a password without specifying it in plain text on the command line. Such a command can be executed both interactively and in batch mode.


Picocli supports POSIX clustered short options:one or more single-character options without option-arguments, followed by at most one option with an option-argument, can be grouped behind one '-' delimiter.


Applications can give a subtle hint to end users that an option is common and encouraged by providing both a short and a long name for an option.Conversely, the absence of a short option can signal that the option is unusual or perhaps should be used with care.


The value of x is false by default, and is set to true (the opposite of the default) if the -x option is specified on the command line.If the -x option is specified multiple times on the command line, the value of x remains true. (Prior to picocli 4.0, the value of x would "toggle" (flip to its opposite) for every -x option on the command line. This can still be configured if required.)


This is enough in most cases, but picocli offers alternatives for applications that need to get the value from something other than the default value. When the option is specified on the command line, the annotated field (or method) is assigned a value, as follows:

3a8082e126
Reply all
Reply to author
Forward
0 new messages