github remkop/picocli v4.0.0-beta-1b
Picocli 4.0.0-beta-1b

latest releases: v4.7.6, v4.7.5, v4.7.4...
5 years ago

Picocli 4.0.0-beta-1b

The picocli community is pleased to announce picocli 4.0.0-beta-1b. (That should have been 4.0.0-beta-1, :-) there were a few hiccups along the way...)

Annotation Processor

This release includes the first cut of an annotation processor that can build a model from the picocli annotations at compile time rather than at runtime.

Use this if you’re interested in:

  • 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.
  • Graal native images. The annotation processor generates Graal configuration
    files under META-INF/native-image/picocli-generated/$project during compilation, to be included in the application jar. By embedding these configuration files, your jar is instantly Graal-enabled. In most cases no further configuration is needed when generating a native image.

Modular

The main picocli-4.x.jar is now an explicit JPMS module, with a module-info.class located in META-INF/versions/9. The picocli-jpms-module subproject has been removed.

Also, from this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact.

Negatable Options

From picocli 4.0, options can be negatable. When an option is negatable, picocli will recognize negative aliases of the option on the command line. See the New and Noteworthy section below for more details.

Feedback Welcome

Please try this and provide feedback. We can still make changes.

What do you think of the @ArgGroup annotations API? What about the programmatic API? Does it work as expected? Are the input validation error messages correct and clear? Is the documentation clear and complete? Anything you want to change or improve? Any other feedback?

Many thanks to the picocli community for the contributions!

This is the fifty-fifth public release.
Picocli follows semantic versioning.

Table of Contents

  • New and noteworthy
  • Fixed issues
  • Deprecations
  • Potential breaking changes

New and Noteworthy

Annotation Processor

This release includes the first cut of an annotation processor that can build a model from the picocli annotations at compile time rather than at runtime.

Use this if you’re interested in:

  • 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.
  • Graal native images. The annotation processor generates and updates Graal configuration files under
    META-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.
    The $project location is configurable, see processor options below.
    In most cases no further configuration is needed when generating a native image.

Enabling the Annotation Processor

Since Java 6, annotation processing is part of the standard javac compiler, but many IDEs and build tools require something extra to enable annotation processing.

IDE

This page shows the steps to configure Eclipse and IntelliJ IDEA to enable annotation processing.

Maven

In Maven, use annotationProcessorPaths in the configuration of the maven-compiler-plugin.
This requires maven-compiler-plugin plugin version 3.5 or higher.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
  <version>${maven-compiler-plugin-version}</version>
  <configuration>
    <annotationProcessorPaths>
      <path>
        <groupId>info.picocli</groupId>
        <artifactId>picocli-codegen</artifactId>
        <version>4.0.0-beta-1b</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

An alternative that works with older versions of the maven-compiler-plugin is to specify the picocli-codegen module on the classpath as a provided dependency. This also prevents the picocli-codegen module from being included in the artifact the module produces as a transitive dependency.

<dependency>
  <groupId>info.picocli</groupId>
  <artifactId>picocli</artifactId>
  <version>4.0.0-beta-1b</version>
</dependency>

<dependency>
  <groupId>info.picocli</groupId>
  <artifactId>picocli-codegen</artifactId>
  <version>4.0.0-beta-1b</version>
  <provided>true</provided>
</dependency>

See Processor Options below.

Gradle

Use the annotationProcessor path in Gradle 4.6 and higher:

dependencies {
    compile 'info.picocli:picocli:4.0.0-beta-1b'
    annotationProcessor 'info.picocli:picocli-codegen:4.0.0-beta-1b'
}

For Gradle versions prior to 4.6, use compileOnly, to prevent the picocli-codegen jar from being a transitive dependency included in the artifact the module produces.

dependencies {
    compile 'info.picocli:picocli:4.0.0-beta-1b'
    compileOnly 'info.picocli:picocli-codegen:4.0.0-beta-1b'
}

Picocli Processor Options

The picocli annotation processor supports the options below.

Recommended Options
  • project - output subdirectory

The generated files are written to META-INF/native-image/picocli-generated/${project}.

The project option can be omitted, but it is a good idea to specify the project option with a unique value for your project (e.g. ${groupId}/${artifactId}) if your jar may be shaded with other jars into an uberjar.

Other Options
  • other.resource.patterns - comma-separated list of regular expressions matching additional resources to include in the image
  • other.resource.bundles - comma-separated list of the base names of additional resource bundles to include in the image
  • other.proxy.interfaces - comma-separated list of the fully qualified class names of additional interfaces for which to generate proxy classes when building the image
  • disable.proxy.config - don’t generate proxy-config.json
  • disable.reflect.config - don’t generate reflect-config.json
  • disable.resource.config - don’t generate resources-config.json
Javac

To pass an annotation processor option with javac, specify the -A command line option:

javac -Aproject=org.myorg.myproject/myapp -cp ...

The -A option lets you pass options to annotation processors. See the javac documentation for details.

Maven

To set an annotation processor option in Maven, you need to use the maven-compiler-plugin and configure the compilerArgs section.

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher -->
      <version>${maven-compiler-plugin-version}</version>
      <configuration>
        <compilerArgs>
          <arg>-Aproject=${groupId}/${artifactId}</arg>
        </compilerArgs>
      </configuration>
    </plugin>
  </plugins>
</build>

See https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html for details.

Gradle Example

To set an annotation processor option in Gradle, add these options to the options.compilerArgs list in the compileJava block.

compileJava {
    // minimum 1.6
    sourceCompatibility = ${java-version}
    targetCompatibility = ${java-version}
    options.compilerArgs += ["-Aproject=${project.group}/${project.name}"]
}

See the Gradle documentation for details.

Negatable Options

From picocli 4.0, options can be negatable.

class App {
    @Option(names = "--verbose",           negatable = true) boolean verbose;
    @Option(names = "-XX:+PrintGCDetails", negatable = true) boolean printGCDetails;
    @Option(names = "-XX:-UseG1GC",        negatable = true) boolean useG1GC = true;
}

When an option is negatable, picocli will recognize negative aliases of the option on the command line.

For *nix-style long options, aliases have the prefix 'no-' to the given names.
For Java JVM-style options, the :+ is turned into :- and vice versa. (This can be changed by customizing the INegatableOptionTransformer.)

If the negated form of the option is found, for example --no-verbose, the value is set to the provided default. Otherwise, with a regular call, for example --verbose, it is set to the opposite of the default.

Fixed issues

  • [#500] Add a generic and extensible picocli annotation processor
  • [#699] Add annotation processor that generates reflect-config.json during build
  • [#703] Add annotation processor that generates resource-config.json during build
  • [#704] Add annotation processor that generates proxy-config.json during build
  • [#707] Add example maven/gradle projects that demonstrate using the annotation processor
  • [#711] API: Create separate picocli-groovy module, make picocli an explicit module (a modular multiversion jar)
  • [#694] API: negatable boolean options. Thanks to Michael D. Adams for the feature request.
  • [#712] Boolean options should not toggle by default, to be consistent with negatable options
  • [#709] Fix scrambled characters for the ± character when running on system with non-UTF8 encoding
  • [#717] Fix unmappable character for encoding ASCII by setting compiler encoding to UTF8 explicitly. Thanks to Liam Esteban Prince for raising this.
  • [#697] Option sort in usage help should ignore option name prefix; long options without short name should be inserted alphabetically, instead of always appear at the top.
  • [#695] Fix runtime warnings about illegal reflective access to field java.io.FilterOutputStream.out. Thanks to gitfineon for reporting this issue.
  • [#698] Reduce reflect-config.json used by GraalVM native-image generation
  • [#700] Change default exit codes to 1 for Exceptions in client code, 2 for invalid usage. Add links to ExitCode javadoc.
  • [#715] processor tests should not fail when running in different locale
  • [#710] Let annotation processor validate negatable options, usageHelp options
  • [#716] Revert @Inherited annotation for @Command. Thanks to Mikusch for raising this.

Deprecations

Potential breaking changes

picocli.groovy Classes Moved to Separate Artifact

From this release the main picocli-4.x artifact no longer contains the picocli.groovy classes: these have been split off into a separate picocli-groovy-4.x artifact.

Scripts upgrading to picocli 4.0 must change more than just the version number!
Scripts should use @Grab('info.picocli:picocli-groovy:4.x') from version 4.0, @Grab('info.picocli:picocli:4.x') will not work.

Option Order Changed

Previously, options that only have a long name (and do not have a short name) were always shown before options with a short name.
From this release, they are inserted in the option list by their first non-prefix letter.
This may break tests that expect a specific help message.

Boolean Options Do Not Toggle By Default

From this release, when a flag option is specified on the command line picocli will set its value to the opposite of its default value.

Prior to 4.0, the default was to "toggle" boolean flags to the opposite of their current value:
if the previous value was true it is set to false, and when the value was false it is set to true.

Applications can call CommandLine.setToggleBooleanFlags(true) to enable toggling.
Note that when toggling is enabled, specifying a flag option twice on the command line will have no effect because they cancel each other out.

Revert @Inherited annotation on @Command

The @Inherited annotated that was added to @Command in picocli 4.0.0-alpha-2 turned out to cause
issues in scenarios with multiple levels of inheritance and is reverted in this release.

Don't miss a new picocli release

NewReleases is sending notifications on new releases.