Skip to content

Commit

Permalink
[#1773] Enhancement: Applications can improve startup time by setting…
Browse files Browse the repository at this point in the history
… system property `picocli.disable.closures` to `true`

Closes #1773
  • Loading branch information
remkop committed Aug 18, 2022
1 parent b313eb9 commit 373ddbf
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
3 changes: 3 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This release includes bugfixes and enhancements.

From this release, applications can programmatically set the trace level, and use tracing in custom components.

Applications can improve startup time by setting system property `picocli.disable.closures` to `true` to disable support for [closures in annotations](https://picocli.info/#_closures_in_annotations).

Also, this release has various fixes and enhancements related to the synopsis of the usage help message.


Expand Down Expand Up @@ -89,6 +91,7 @@ Picocli 4.7.0 introduced a `sortSynopsis = false` attribute to let the synopsis
* [#1571] Enhancement: Variables in values from the default value provider should be interpolated. Thanks to [Bas Passon](https://github.com/bpasson) for raising this.
* [#1574] API: Add annotation API to control whether synopsis should be sorted alphabetically or by explicit `order`.
* [#1708][#1712][#1723] API: The `setUsageHelpLongOptionsMaxWidth` method no longer throws an exception when an invalid value is specified; instead, the value is ignored and an INFO-level trace message is logged. Thanks to [Fabio](https://github.com/fabio-franco) for the pull request.
* [#1773] Enhancement: Applications can improve startup time by setting system property `picocli.disable.closures` to `true` to disable support for [closures in annotations](https://picocli.info/#_closures_in_annotations). Thanks to [patric-r](https://github.com/patric-r) for raising this.
* [#1408] Enhancement: Synopsis should respect `order` if specified. Thanks to [Simon](https://github.com/sbernard31) for raising this.
* [#964][#1080] Enhancement: ArgGroup synopsis should respect `order` (if specified). Thanks to [Enderaoe](https://github.com/Lyther) for the pull request with unit tests.
* [#1706][#1710] Enhancement: Subcommands should get missing messages from parent command resource bundle. Thanks to [Ruud Senden](https://github.com/rsenden) and [Mike Snowden](https://github.com/wtfacoconut) for the pull request.
Expand Down
1 change: 1 addition & 0 deletions docs/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13072,6 +13072,7 @@ As you can see in the above example, each closure in the annotation should conta
<4> Option or Parameters `parameterConsumer`: given a `Stack`, `ArgSpec` and `CommandSpec`, process the remaining arguments. The closure must be cast to `IParameterConsumer`.
<5> Option or Parameters type `converter` takes an array of closures. Groovy 3.0.7 or greater is required: older versions of Groovy ignore closures in class array annotations. Each closure must have a parameter and be cast to `ITypeConverter`.

NOTE: From picocli version 4.7.0, this feature can be disabled by setting system property `picocli.disable.closures` to `true`. Disabling support for closures in annotations can improve the application startup time.

==== Older Versions of Groovy
NOTE: When using a Groovy version older than 2.4.7, use this workaround for the https://issues.apache.org/jira/browse/GROOVY-7613[Grape bug] that causes this error:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package picocli.groovy

import org.junit.AfterClass
import org.junit.BeforeClass
import org.junit.Test
import picocli.CommandLine
import picocli.CommandLine.InitializationException

class ClosureInAnnotationsDisabledTest {
@BeforeClass
public static void beforeClass() {
System.setProperty("picocli.disable.closures", "true")
}

@AfterClass
public static void afterClass() {
System.clearProperty("picocli.disable.closures")
}


@CommandLine.Command(name = "ClosureDemo",
versionProvider = { {-> ["line1" , "line2"] as String[] } as CommandLine.IVersionProvider },
defaultValueProvider = {{argSpec -> "some default" } as CommandLine.IDefaultValueProvider}
)
static class ClosureDemo {
@CommandLine.Option(names = '-x', completionCandidates = {["A", "B", "C"]})
String x

@CommandLine.Option(names = '-y',
parameterConsumer = {{args, argSpec, commandSpec ->
argSpec.setValue(args.toString() + commandSpec.name())
args.clear()
} as CommandLine.IParameterConsumer })
String y
}

@Test
void testClosureDemo() {
try {
new CommandLine(new ClosureDemo())
} catch (InitializationException ex) {
String name = ClosureDemo.class.getName()
assert ex.message.startsWith("Cannot instantiate ${name}\$_closure1: the class has no constructor")
}
}

}
4 changes: 4 additions & 0 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -5612,6 +5612,10 @@ public interface IFactory {
private static class DefaultFactory implements IFactory {
static Class<?> GROOVY_CLOSURE_CLASS = loadClosureClass();
private static Class<?> loadClosureClass() {
if (Boolean.getBoolean("picocli.disable.closures")) {
tracer().info("DefaultFactory: groovy Closures in annotations are disabled and will not be loaded");
return null;
}
try { return Class.forName("groovy.lang.Closure"); }
catch (Exception ignored) { return null;}
}
Expand Down

0 comments on commit 373ddbf

Please sign in to comment.