Should System.exit be controlled by a Scope Local?

Remi Forax forax at univ-mlv.fr
Sun Feb 27 13:01:47 UTC 2022


Hi Ethan,
there is a far simpler solution, call org.apache.ivy.run(args, true) instead of org.apache.ivy.main(args) in your tool provider.

regards,
Rémi

----- Original Message -----
> From: "Ethan McCue" <ethan at mccue.dev>
> To: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Sent: Saturday, February 26, 2022 11:14:19 PM
> Subject: Should System.exit be controlled by a Scope Local?

> I have a feeling this has been considered and I might just be articulating
> the obvious - but:
> 
> As called out in JEP 411, one of the remaining legitimate uses of the
> Security Manager is to intercept calls to System.exit. This seems like a
> decent use case for the Scope Local mechanism.
> 
> 
>    public class Runtime {
>        ...
>        private final ScopeLocal<IntConsumer> EXIT =
> ScopeLocal.newInstance();
> 
>        ...
> 
>        public void overridingExitBehavior(IntConsumer exit, Runnable run) {
>            ScopeLocal.with(EXIT, exit).run(run);
>        }
> 
>        ...
> 
>        public void exit(int status) {
>            if (EXIT.isBound()) {
>                EXIT.get().accept(status);
>            }
>            else {
>                Shutdown.exit(status);
>            }
>        }
>    }
> 
> 
> One of the likely minor benefits in the scope of things, but related to the
> parts of the ecosystem I am doodling with so I'll mention it, is that it
> would become possible to wrap "naive" cli programs with the ToolProvider
> SPI without rewriting their code if this System.out, and System.err all
> became reliably configurable.
> 
> For instance, Apache Ivy's CLI has a main class that looks like this
> 
> https://github.com/apache/ant-ivy/blob/424fa89419147f50a41b4bdc665d8ea92b5da516/src/java/org/apache/ivy/Main.java
> 
>    package org.apache.ivy;
> 
>    public final class Main {
>        ...
> 
>        public static void main(String[] args) throws Exception {
>            try {
>                run(args, true);
>                System.exit(0);
>            } catch (ParseException ex) {
>                System.err.println(ex.getMessage());
>                System.exit(1);
>            }
>        }
>     }
> 
> Making these otherwise static parts of the system configurable would enable
> a third party library to write
> 
>    public final class IvyToolProvider implements ToolProvider {
>        @Override
>        public String name() {
>            return "ivy";
>        }
> 
>        @Override
>        public int run(PrintWriter out, PrintWriter err, String... args) {
>            var exit = new AtomicInteger(0);
>            Runtime.getRuntime().overridingExitBehavior(exit::set, () -> {
>                System.overridingOut(out, () -> {
>                     System.overridingErr(err, Main::main);
>                }
>            };
>            return exit.get();
>        }
>    }
> 
> Whether that would be enough to make it so that people other than Christian
> Stein use the mechanism is anyone's guess, but might be worth a shot.
> 
> https://grep.app/search?q=java.util.spi.ToolProvider


More information about the core-libs-dev mailing list