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 underMETA-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 imageother.resource.bundles
- comma-separated list of the base names of additional resource bundles to include in the imageother.proxy.interfaces
- comma-separated list of the fully qualified class names of additional interfaces for which to generate proxy classes when building the imagedisable.proxy.config
- don’t generateproxy-config.json
disable.reflect.config
- don’t generatereflect-config.json
disable.resource.config
- don’t generateresources-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, makepicocli
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 toExitCode
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.