From 28ddf40f338a83d00eaa96ab73cde17560c0d27e Mon Sep 17 00:00:00 2001 From: Tadaya Tsuyukubo Date: Sun, 23 Oct 2022 08:35:27 -0700 Subject: [PATCH 1/2] Document System.exit usage Resolves #1855 Signed-off-by: Tadaya Tsuyukubo --- docs/index.adoc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/index.adoc b/docs/index.adoc index 38e75eff2..fcfa2c78f 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -3620,6 +3620,9 @@ fun main(args: Array) { CAUTION: Older versions of picocli had some limited exit code support where picocli would call `System.exit`, but this is now deprecated. +When an application is not appropriate to call `System.exit`, for example it runs on the caller's process, you can take a different action based on the returned `int`. +See <> section for the usecases. + === Generating an Exit Code `@Command`-annotated classes that implement `Callable` and `@Command`-<> can simply return an `int` or `Integer`, and this value will be returned from `CommandLine.execute`. For example: @@ -11401,6 +11404,31 @@ Multi-line text blocks can be used in command and option descriptions, headers a For more details, see https://www.infoq.com/articles/java-text-blocks/[this article] by Java Language Architect Brian Goetz. +=== Usage of `System.exit` + +When an application runs as an independent process, `System.exit` returns an exit code to the caller. +On the other hand, when an application runs as part of the caller process, `System.exit` halts the caller process and ends up an abrupt finish. + +In such scenario, you need to avoid `System.exit`. + +For example, picocli based <> solves this problem by having link:autocomplete.html#_maven_example[a system property] to determine whether to call `System.exit`. + +Another usecase is https://www.mojohaus.org/exec-maven-plugin/[`exec-maven-plugin`] with https://www.mojohaus.org/exec-maven-plugin/java-mojo.html[`exec:java` goal]. +This goal invokes the target class on the same maven process. +The `System.exit` call finishes maven process bypassing the rest of the maven steps including its error handlings. + +In picocli, any exceptions thrown during the `CommandLine.execute` method are captured, printed, and converted to an exit code. +You can check the exit code and perform an appropriate action, such as throwing an exception, instead of calling `System.exit`. +Then, the caller(maven process) could perform its exception handlings. + +[source,java] +---- +int exitCode = new CommandLine(new MyCommand()).execute(args); +if (exitCode != ExitCode.OK) { + throw new IllegalStateException("MyCommand failed"); +} +---- + == Dependency Injection From 1fe963b1f5a5c74b96e0c1170d5b5d4ae13fff8b Mon Sep 17 00:00:00 2001 From: Tadaya Tsuyukubo Date: Wed, 2 Nov 2022 21:10:34 -0700 Subject: [PATCH 2/2] Apply feedback --- docs/index.adoc | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/index.adoc b/docs/index.adoc index fcfa2c78f..6c9dded63 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -3620,8 +3620,7 @@ fun main(args: Array) { CAUTION: Older versions of picocli had some limited exit code support where picocli would call `System.exit`, but this is now deprecated. -When an application is not appropriate to call `System.exit`, for example it runs on the caller's process, you can take a different action based on the returned `int`. -See <> section for the usecases. +There are cases where calling `System.exit` is not ideal. See <> for details. === Generating an Exit Code @@ -11409,25 +11408,16 @@ For more details, see https://www.infoq.com/articles/java-text-blocks/[this arti When an application runs as an independent process, `System.exit` returns an exit code to the caller. On the other hand, when an application runs as part of the caller process, `System.exit` halts the caller process and ends up an abrupt finish. -In such scenario, you need to avoid `System.exit`. - For example, picocli based <> solves this problem by having link:autocomplete.html#_maven_example[a system property] to determine whether to call `System.exit`. -Another usecase is https://www.mojohaus.org/exec-maven-plugin/[`exec-maven-plugin`] with https://www.mojohaus.org/exec-maven-plugin/java-mojo.html[`exec:java` goal]. +Another use case is https://www.mojohaus.org/exec-maven-plugin/[`exec-maven-plugin`] with https://www.mojohaus.org/exec-maven-plugin/java-mojo.html[`exec:java` goal]. This goal invokes the target class on the same maven process. The `System.exit` call finishes maven process bypassing the rest of the maven steps including its error handlings. -In picocli, any exceptions thrown during the `CommandLine.execute` method are captured, printed, and converted to an exit code. -You can check the exit code and perform an appropriate action, such as throwing an exception, instead of calling `System.exit`. -Then, the caller(maven process) could perform its exception handlings. - -[source,java] ----- -int exitCode = new CommandLine(new MyCommand()).execute(args); -if (exitCode != ExitCode.OK) { - throw new IllegalStateException("MyCommand failed"); -} ----- +In such scenarios, you should use `parseArgs` instead. +You can control whether to propagate the exception to the caller. +Then, the caller(e.g. maven process) can perform its exception handlings. +See <> for details. == Dependency Injection