Re: Should System.exit be controlled by a Scope Local?

2022-03-15 Thread Andrew Haley

On 3/1/22 18:17, Sean Mullan wrote:

Can you explain in a little more detail as to what the compatibility
issues are with preventing threads in thread pools from calling System.exit?


It is possible, I suppose, that some rather odd programmer is using
a task in a thread pool to exit their program. I know, unlikely, but
we preserve compatibility.

--
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. 
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


Re: Should System.exit be controlled by a Scope Local?

2022-03-02 Thread Maurizio Cimadamore



On 01/03/2022 18:17, Sean Mullan wrote:



On 3/1/22 8:01 AM, Andrew Haley wrote:

On 3/1/22 11:45, Andrew Haley wrote:

Sure, you wouldn't
be able to use the default thread pool, but that's no big deal, I 
would have

thought.


I'm sorry, I'll say that again. :-)


I meant to say "you wouldn't be able to use the default thread pool if
you wanted to use threads with some restrictions (e.g those that 
couldn't

invoke System.exit()).


Can you explain in a little more detail as to what the compatibility 
issues are with preventing threads in thread pools from calling 
System.exit?


AFAIU, I believe the issue is that threads in the default pool are 
created early, so they don't see the scope local which overrides the 
semantics of System.exit.


Only threads created _after_ the scope local is set would see the 
overridden/restricted semantics.


Maurizio



Thanks,
Sean


Re: Should System.exit be controlled by a Scope Local?

2022-03-01 Thread Sean Mullan




On 3/1/22 8:01 AM, Andrew Haley wrote:

On 3/1/22 11:45, Andrew Haley wrote:

Sure, you wouldn't
be able to use the default thread pool, but that's no big deal, I would have
thought.


I'm sorry, I'll say that again. :-)


I meant to say "you wouldn't be able to use the default thread pool if
you wanted to use threads with some restrictions (e.g those that couldn't
invoke System.exit()).


Can you explain in a little more detail as to what the compatibility 
issues are with preventing threads in thread pools from calling System.exit?


Thanks,
Sean


Re: Should System.exit be controlled by a Scope Local?

2022-03-01 Thread Andrew Haley

On 3/1/22 11:45, Andrew Haley wrote:

Sure, you wouldn't
be able to use the default thread pool, but that's no big deal, I would have
thought.


I'm sorry, I'll say that again. :-)


I meant to say "you wouldn't be able to use the default thread pool if
you wanted to use threads with some restrictions (e.g those that couldn't
invoke System.exit()).

--
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. 
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


Re: Should System.exit be controlled by a Scope Local?

2022-03-01 Thread Andrew Haley

On 2/28/22 15:32, Andrew Haley wrote:


I think all we'd need is a set of capabilities bound to a scope local
at thread startup, and I guess it'd default to "all capabilities".
Trusted code could then override any of those capabilities.

We'd have to make sure that capabilities were inherited by threads,
and we'd have to think very carefully about thread pools. The problem
there is that while it would (I guess) make sense to prevent all code
executing in thread pools from calling System.exit(), there's an
obvious compatibility problem if it can't.


Although... there certainly is some potential profit in restricted thread
pools, which have no compatibility problems because it'd be a new feature.
I think this solves the problem Alan Bateman raised too. Sure, you wouldn't
be able to use the default thread pool, but that's no big deal, I would have
thought.

--
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. 
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Bernd Eckenfels
Alternatively you can make this “first setter wins” (either globally or per 
thread), then you don’t have to care or check from where the call is coming. 
Could be even integrated with a system property similar to the 
securitymanager=allow.

Gruss
Bernd


--
http://bernd.eckenfels.net

Von: core-libs-dev  im Auftrag von Kasper 
Nielsen 
Gesendet: Monday, February 28, 2022 9:23:11 PM
An: Ethan McCue 
Cc: core-libs-dev 
Betreff: Re: Should System.exit be controlled by a Scope Local?

Is there really a need to make this so complicated?

In all the examples I've seen so far it would be fine to set
system-exit restrictions up from the program's main class.
So why not just restrict it to the main class by default?
I assume this class is under the control of the user or
an IDE/Application Server.

Add this method to java.lang.Runtime

void restrictExit(MethodHandles.Lookup lookup, IntConsumer interceptor) {
  if (lookup.lookupClass() != "JAVA_MAIN_CLASS" ||
!lookup.hasFullPrivilegeAccess())
{
 throw new IllegalArgumentException("Invalid Lookup class");
  }
  ...
  Register interceptor to be called before System.exit
  ...
}

People could then call it, for example, from a static initializer block in
the
Main class. And use scope locals or whatever they want.

static {
  Runtime.restrictExit(MethodHandles.lookup(), ...)
}

Ideally, everyone would be using the module system, And we would have some
kind
of "application module" concept, which would be the module containing the
program's entry point. And which could have these special permissions by
default.
It might even be possible to delegate permissions to other modules if
needed.

/Kasper

On Sat, 26 Feb 2022 at 22:27, Ethan McCue  wrote:

> 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.
>
>
>


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Kasper Nielsen
Is there really a need to make this so complicated?

In all the examples I've seen so far it would be fine to set
system-exit restrictions up from the program's main class.
So why not just restrict it to the main class by default?
I assume this class is under the control of the user or
an IDE/Application Server.

Add this method to java.lang.Runtime

void restrictExit(MethodHandles.Lookup lookup, IntConsumer interceptor) {
  if (lookup.lookupClass() != "JAVA_MAIN_CLASS" ||
!lookup.hasFullPrivilegeAccess())
{
 throw new IllegalArgumentException("Invalid Lookup class");
  }
  ...
  Register interceptor to be called before System.exit
  ...
}

People could then call it, for example, from a static initializer block in
the
Main class. And use scope locals or whatever they want.

static {
  Runtime.restrictExit(MethodHandles.lookup(), ...)
}

Ideally, everyone would be using the module system, And we would have some
kind
of "application module" concept, which would be the module containing the
program's entry point. And which could have these special permissions by
default.
It might even be possible to delegate permissions to other modules if
needed.

/Kasper

On Sat, 26 Feb 2022 at 22:27, Ethan McCue  wrote:

> 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.
>
>
>


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Andrew Haley

On 2/28/22 15:12, Sean Mullan wrote:
>
> On 2/27/22 1:47 PM, Andrew Haley wrote:
>
>> I'd like to explore the use of scope locals as a lightweight means to
>> implement a system of permissions and capabilities for things such as
>> this.
>
> Now you have piqued my curiosity, as I have explored a capability based
> model for intercepting `System.exit`. Can you say any more about this yet?

I think all we'd need is a set of capabilities bound to a scope local
at thread startup, and I guess it'd default to "all capabilities".
Trusted code could then override any of those capabilities.

We'd have to make sure that capabilities were inherited by threads,
and we'd have to think very carefully about thread pools. The problem
there is that while it would (I guess) make sense to prevent all code
executing in thread pools from calling System.exit(), there's an
obvious compatibility problem if it can't.

--
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. 
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Sean Mullan




On 2/27/22 1:47 PM, Andrew Haley wrote:


I'd like to explore the use of scope locals as a lightweight means to
implement a system of permissions and capabilities for things such as
this.


Now you have piqued my curiosity, as I have explored a capability based 
model for intercepting `System.exit`. Can you say any more about this yet?


Thanks,
Sean


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Ethan McCue
Where would be a good place to do that sort of surveying? The mechanism
does not seem to be that popular in open source software ( though that does
make a degree of sense ), or at least the software grep.app scans

https://grep.app/search?q=permission.getName%28%29.startsWith%28%22exitVM%22%29


On Mon, Feb 28, 2022 at 9:05 AM Alan Bateman 
wrote:

> On 26/02/2022 22:14, Ethan McCue wrote:
> > 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.
> >
> I think it was mostly convenience to use the SM to intercept calls to
> System.exit as it's not really security when all other permissions are
> granted.
>
> There have been a few prototypes of APIs in this area but none made to
> the level of a good proposal. Using a SL or even TL set/remove is
> interesting but you might want to survey some of the existing usages to
> see if they are really stack confined. At least some of the uses have
> been container applications with plugins that accidentally call
> System.exit when running code not intended to run that way. I don't
> think there is any guarantee that they run completely in the same thread
> but some may do.
>
> -Alan
>


Re: Should System.exit be controlled by a Scope Local?

2022-02-28 Thread Alan Bateman

On 26/02/2022 22:14, Ethan McCue wrote:

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.

I think it was mostly convenience to use the SM to intercept calls to 
System.exit as it's not really security when all other permissions are 
granted.


There have been a few prototypes of APIs in this area but none made to 
the level of a good proposal. Using a SL or even TL set/remove is 
interesting but you might want to survey some of the existing usages to 
see if they are really stack confined. At least some of the uses have 
been container applications with plugins that accidentally call 
System.exit when running code not intended to run that way. I don't 
think there is any guarantee that they run completely in the same thread 
but some may do.


-Alan


Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Ethan McCue
K.

On Sun, Feb 27, 2022, 7:03 PM David Holmes  wrote:

> On 28/02/2022 8:20 am, Ethan McCue wrote:
> > My understanding is that when you System.exit all threads associated
> > with the JVM process are killed. That's what I meant by "nuclear
> > Thread.interrupt".
>
> The process is terminated, the threads are not individually "killed".
> All Thread.interrupt does is set a flag and unpark blocked threads (in
> some specific cases). There's really no comparison at all.
>
> David
> -
>
> > It's the same issue as was raised about System.exit implicitly ending
> > control flow or implicitly closing open file handles - a process could
> > be relying on the behavior of implicitly killing all threads and not
> > have another cleanup mechanism
> >
> > On Sun, Feb 27, 2022, 5:16 PM David Holmes  > <mailto:david.hol...@oracle.com>> wrote:
> >
> > On 28/02/2022 3:20 am, Ethan McCue wrote:
> >  > I think continuations could work for the single threaded case,
> > depending on
> >  > their behavior with "finally" blocks. I'm sure there are more
> > caveats once
> >  > we add another thread to the mix though. System.exit is a nuclear
> >  > Thread.interrupt, so replicating that behavior might be a bit
> > daunting
> >
> > What has Thread.interrupt got to do with System.exit ?
> >
> > David
> >
> >  >  private static final class ExitCode {
> >  >  volatile Integer code = null;
> >  >  }
> >  >
> >  >  private final ScopeLocal EXIT_CODE =
> > ScopeLocal.newInstance();
> >  >
> >  >  public void overridingExitBehavior(IntConsumer exit,
> > Runnable run) {
> >  >  var exitCode = new ExitCode();
> >  >  ScopeLocal.with(EXIT_CODE, exitCode).run(() -> {
> >  >  // by whatever syntax
> >  >  var _ = inContinuation(run);
> >  >  if (exitCode.code != null) {
> >  >  exit.accept(code.exitCode)
> >  >  }
> >  >  });
> >  >  }
> >  >
> >  >  public void exit(int status) {
> >  >  if (EXIT_CODE.isBound()) {
> >  >   EXIT_CODE.get().code = status;
> >  >   Continuation.yield();
> >  >  }
> >  >  else {
> >  >  Shutdown.exit(status);
> >  >  }
> >  >  }
> >  >
> >  >
> >  >
> >  > On Sun, Feb 27, 2022 at 10:41 AM Glavo  > <mailto:zjx001...@gmail.com>> wrote:
> >  >
> >  >> I think there is a problem with this: `System.exit` contains
> > semantics to
> >  >> interrupt the flow of control and exit, and if you implement it
> > that way,
> >  >> you might have some program abnormally execute parts of it that
> > should
> >  >> never be executed.
> >  >>
> >  >> Of course, using exceptions like this should solve part of the
> > problem:
> >  >>
> >  >> class Exit extends Error {
> >  >>  final int exitCode;
> >  >>  public Exit(int exitCode) {
> >  >>  this.exitCode = exitCode;
> >  >>  }
> >  >>
> >  >>  @Override
> >  >>  public synchronized Throwable fillInStackTrace() {
> >  >>  return this;
> >  >>  }
> >  >> }
> >  >>
> >  >> try {
> >  >>Runtime.getRuntime().overridingExitBehavior(exitCode ->
> > {throw new
> >  >> Exit(exitCode);}, ...);
> >  >> } catch (Exit exit) {
> >  >>...
> >  >> }
> >  >>
> >  >> However, the calling method may catch this exception
> > unexpectedly, and
> >  >> there may be unexpected behavior under multithreading.
> >  >> Of course, this part of the problem also exists for the security
> > manager.
> >  >> But, if possible, it would be better to have a solution for these
> >  >> situations.
> >  >> (`Continuation` might help us?)
> >  >>
> >  >>
> >  >>
&

Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread David Holmes

On 28/02/2022 8:20 am, Ethan McCue wrote:
My understanding is that when you System.exit all threads associated 
with the JVM process are killed. That's what I meant by "nuclear 
Thread.interrupt".


The process is terminated, the threads are not individually "killed". 
All Thread.interrupt does is set a flag and unpark blocked threads (in 
some specific cases). There's really no comparison at all.


David
-

It's the same issue as was raised about System.exit implicitly ending 
control flow or implicitly closing open file handles - a process could 
be relying on the behavior of implicitly killing all threads and not 
have another cleanup mechanism


On Sun, Feb 27, 2022, 5:16 PM David Holmes <mailto:david.hol...@oracle.com>> wrote:


On 28/02/2022 3:20 am, Ethan McCue wrote:
 > I think continuations could work for the single threaded case,
depending on
 > their behavior with "finally" blocks. I'm sure there are more
caveats once
 > we add another thread to the mix though. System.exit is a nuclear
 > Thread.interrupt, so replicating that behavior might be a bit
daunting

What has Thread.interrupt got to do with System.exit ?

David

 >      private static final class ExitCode {
 >          volatile Integer code = null;
 >      }
 >
 >      private final ScopeLocal EXIT_CODE =
ScopeLocal.newInstance();
 >
 >      public void overridingExitBehavior(IntConsumer exit,
Runnable run) {
 >          var exitCode = new ExitCode();
 >          ScopeLocal.with(EXIT_CODE, exitCode).run(() -> {
 >              // by whatever syntax
 >              var _ = inContinuation(run);
 >              if (exitCode.code != null) {
 >                  exit.accept(code.exitCode)
 >              }
 >          });
 >      }
 >
 >      public void exit(int status) {
 >          if (EXIT_CODE.isBound()) {
 >               EXIT_CODE.get().code = status;
 >               Continuation.yield();
 >          }
 >          else {
 >              Shutdown.exit(status);
 >          }
 >      }
 >
 >
 >
 > On Sun, Feb 27, 2022 at 10:41 AM Glavo mailto:zjx001...@gmail.com>> wrote:
 >
 >> I think there is a problem with this: `System.exit` contains
semantics to
 >> interrupt the flow of control and exit, and if you implement it
that way,
 >> you might have some program abnormally execute parts of it that
should
 >> never be executed.
 >>
 >> Of course, using exceptions like this should solve part of the
problem:
 >>
 >> class Exit extends Error {
 >>      final int exitCode;
 >>      public Exit(int exitCode) {
 >>          this.exitCode = exitCode;
 >>      }
 >>
 >>      @Override
 >>      public synchronized Throwable fillInStackTrace() {
 >>          return this;
 >>      }
 >> }
 >>
 >> try {
 >>    Runtime.getRuntime().overridingExitBehavior(exitCode ->
{throw new
 >> Exit(exitCode);}, ...);
 >> } catch (Exit exit) {
 >>    ...
 >> }
 >>
 >> However, the calling method may catch this exception
unexpectedly, and
 >> there may be unexpected behavior under multithreading.
 >> Of course, this part of the problem also exists for the security
manager.
 >> But, if possible, it would be better to have a solution for these
 >> situations.
 >> (`Continuation` might help us?)
 >>
 >>
 >>
 >> On Sun, Feb 27, 2022 at 11:07 PM Ethan McCue mailto:et...@mccue.dev>> wrote:
 >>
 >>> That undermines my point some, but I think the overall shape of
the use
 >>> case still makes sense
 >>>
 >>> On Sun, Feb 27, 2022 at 8:01 AM Remi Forax mailto:fo...@univ-mlv.fr>> wrote:
 >>>
 >>>> 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" mailto:et...@mccue.dev>>
 >>>>> To: "core-libs-dev" mailto:core-libs-dev@openjdk.java.net>>
 >>>>> Sent: Saturday, February 26, 2022 11:14:19 PM
 >>

Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Ethan McCue
My understanding is that when you System.exit all threads associated with
the JVM process are killed. That's what I meant by "nuclear
Thread.interrupt".

It's the same issue as was raised about System.exit implicitly ending
control flow or implicitly closing open file handles - a process could be
relying on the behavior of implicitly killing all threads and not have
another cleanup mechanism

On Sun, Feb 27, 2022, 5:16 PM David Holmes  wrote:

> On 28/02/2022 3:20 am, Ethan McCue wrote:
> > I think continuations could work for the single threaded case, depending
> on
> > their behavior with "finally" blocks. I'm sure there are more caveats
> once
> > we add another thread to the mix though. System.exit is a nuclear
> > Thread.interrupt, so replicating that behavior might be a bit daunting
>
> What has Thread.interrupt got to do with System.exit ?
>
> David
>
> >  private static final class ExitCode {
> >  volatile Integer code = null;
> >  }
> >
> >  private final ScopeLocal EXIT_CODE =
> ScopeLocal.newInstance();
> >
> >  public void overridingExitBehavior(IntConsumer exit, Runnable run) {
> >  var exitCode = new ExitCode();
> >  ScopeLocal.with(EXIT_CODE, exitCode).run(() -> {
> >  // by whatever syntax
> >  var _ = inContinuation(run);
> >  if (exitCode.code != null) {
> >  exit.accept(code.exitCode)
> >  }
> >  });
> >  }
> >
> >  public void exit(int status) {
> >  if (EXIT_CODE.isBound()) {
> >   EXIT_CODE.get().code = status;
> >   Continuation.yield();
> >  }
> >  else {
> >  Shutdown.exit(status);
> >  }
> >  }
> >
> >
> >
> > On Sun, Feb 27, 2022 at 10:41 AM Glavo  wrote:
> >
> >> I think there is a problem with this: `System.exit` contains semantics
> to
> >> interrupt the flow of control and exit, and if you implement it that
> way,
> >> you might have some program abnormally execute parts of it that should
> >> never be executed.
> >>
> >> Of course, using exceptions like this should solve part of the problem:
> >>
> >> class Exit extends Error {
> >>  final int exitCode;
> >>  public Exit(int exitCode) {
> >>  this.exitCode = exitCode;
> >>  }
> >>
> >>  @Override
> >>  public synchronized Throwable fillInStackTrace() {
> >>  return this;
> >>  }
> >> }
> >>
> >> try {
> >>Runtime.getRuntime().overridingExitBehavior(exitCode -> {throw new
> >> Exit(exitCode);}, ...);
> >> } catch (Exit exit) {
> >>...
> >> }
> >>
> >> However, the calling method may catch this exception unexpectedly, and
> >> there may be unexpected behavior under multithreading.
> >> Of course, this part of the problem also exists for the security
> manager.
> >> But, if possible, it would be better to have a solution for these
> >> situations.
> >> (`Continuation` might help us?)
> >>
> >>
> >>
> >> On Sun, Feb 27, 2022 at 11:07 PM Ethan McCue  wrote:
> >>
> >>> That undermines my point some, but I think the overall shape of the use
> >>> case still makes sense
> >>>
> >>> On Sun, Feb 27, 2022 at 8:01 AM Remi Forax  wrote:
> >>>
> >>>> 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" 
> >>>>> To: "core-libs-dev" 
> >>>>> 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 

Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread David Holmes

On 28/02/2022 3:20 am, Ethan McCue wrote:

I think continuations could work for the single threaded case, depending on
their behavior with "finally" blocks. I'm sure there are more caveats once
we add another thread to the mix though. System.exit is a nuclear
Thread.interrupt, so replicating that behavior might be a bit daunting


What has Thread.interrupt got to do with System.exit ?

David


 private static final class ExitCode {
 volatile Integer code = null;
 }

 private final ScopeLocal EXIT_CODE = ScopeLocal.newInstance();

 public void overridingExitBehavior(IntConsumer exit, Runnable run) {
 var exitCode = new ExitCode();
 ScopeLocal.with(EXIT_CODE, exitCode).run(() -> {
 // by whatever syntax
 var _ = inContinuation(run);
 if (exitCode.code != null) {
 exit.accept(code.exitCode)
 }
 });
 }

 public void exit(int status) {
 if (EXIT_CODE.isBound()) {
  EXIT_CODE.get().code = status;
  Continuation.yield();
 }
 else {
 Shutdown.exit(status);
 }
 }



On Sun, Feb 27, 2022 at 10:41 AM Glavo  wrote:


I think there is a problem with this: `System.exit` contains semantics to
interrupt the flow of control and exit, and if you implement it that way,
you might have some program abnormally execute parts of it that should
never be executed.

Of course, using exceptions like this should solve part of the problem:

class Exit extends Error {
 final int exitCode;
 public Exit(int exitCode) {
 this.exitCode = exitCode;
 }

 @Override
 public synchronized Throwable fillInStackTrace() {
 return this;
 }
}

try {
   Runtime.getRuntime().overridingExitBehavior(exitCode -> {throw new
Exit(exitCode);}, ...);
} catch (Exit exit) {
   ...
}

However, the calling method may catch this exception unexpectedly, and
there may be unexpected behavior under multithreading.
Of course, this part of the problem also exists for the security manager.
But, if possible, it would be better to have a solution for these
situations.
(`Continuation` might help us?)



On Sun, Feb 27, 2022 at 11:07 PM Ethan McCue  wrote:


That undermines my point some, but I think the overall shape of the use
case still makes sense

On Sun, Feb 27, 2022 at 8:01 AM Remi Forax  wrote:


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" 
To: "core-libs-dev" 
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 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.overridin

Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Andrew Haley

On 2/26/22 22:14, Ethan McCue wrote:

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.


It could well be. One problem, at least in the preview version of scope locals,
is that scope locals are only inherited in a structured concurrency context,
so it wouldn't protect against starting a new Thread which then called
System.exit().

I'd like to explore the use of scope locals as a lightweight means to
implement a system of permissions and capabilities for things such as
this.

--
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. 
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Ethan McCue
I think continuations could work for the single threaded case, depending on
their behavior with "finally" blocks. I'm sure there are more caveats once
we add another thread to the mix though. System.exit is a nuclear
Thread.interrupt, so replicating that behavior might be a bit daunting

private static final class ExitCode {
volatile Integer code = null;
}

private final ScopeLocal EXIT_CODE = ScopeLocal.newInstance();

public void overridingExitBehavior(IntConsumer exit, Runnable run) {
var exitCode = new ExitCode();
ScopeLocal.with(EXIT_CODE, exitCode).run(() -> {
// by whatever syntax
var _ = inContinuation(run);
if (exitCode.code != null) {
exit.accept(code.exitCode)
}
});
}

public void exit(int status) {
if (EXIT_CODE.isBound()) {
 EXIT_CODE.get().code = status;
 Continuation.yield();
}
else {
Shutdown.exit(status);
}
}



On Sun, Feb 27, 2022 at 10:41 AM Glavo  wrote:

> I think there is a problem with this: `System.exit` contains semantics to
> interrupt the flow of control and exit, and if you implement it that way,
> you might have some program abnormally execute parts of it that should
> never be executed.
>
> Of course, using exceptions like this should solve part of the problem:
>
> class Exit extends Error {
> final int exitCode;
> public Exit(int exitCode) {
> this.exitCode = exitCode;
> }
>
> @Override
> public synchronized Throwable fillInStackTrace() {
> return this;
> }
> }
>
> try {
>   Runtime.getRuntime().overridingExitBehavior(exitCode -> {throw new
> Exit(exitCode);}, ...);
> } catch (Exit exit) {
>   ...
> }
>
> However, the calling method may catch this exception unexpectedly, and
> there may be unexpected behavior under multithreading.
> Of course, this part of the problem also exists for the security manager.
> But, if possible, it would be better to have a solution for these
> situations.
> (`Continuation` might help us?)
>
>
>
> On Sun, Feb 27, 2022 at 11:07 PM Ethan McCue  wrote:
>
>> That undermines my point some, but I think the overall shape of the use
>> case still makes sense
>>
>> On Sun, Feb 27, 2022 at 8:01 AM Remi Forax  wrote:
>>
>> > 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" 
>> > > To: "core-libs-dev" 
>> > > 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 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 

Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Glavo
I think there is a problem with this: `System.exit` contains semantics to
interrupt the flow of control and exit, and if you implement it that way,
you might have some program abnormally execute parts of it that should
never be executed.

Of course, using exceptions like this should solve part of the problem:

class Exit extends Error {
final int exitCode;
public Exit(int exitCode) {
this.exitCode = exitCode;
}

@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}

try {
  Runtime.getRuntime().overridingExitBehavior(exitCode -> {throw new
Exit(exitCode);}, ...);
} catch (Exit exit) {
  ...
}

However, the calling method may catch this exception unexpectedly, and
there may be unexpected behavior under multithreading.
Of course, this part of the problem also exists for the security manager.
But, if possible, it would be better to have a solution for these
situations.
(`Continuation` might help us?)



On Sun, Feb 27, 2022 at 11:07 PM Ethan McCue  wrote:

> That undermines my point some, but I think the overall shape of the use
> case still makes sense
>
> On Sun, Feb 27, 2022 at 8:01 AM Remi Forax  wrote:
>
> > 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" 
> > > To: "core-libs-dev" 
> > > 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 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
> >
>


Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Ethan McCue
That undermines my point some, but I think the overall shape of the use
case still makes sense

On Sun, Feb 27, 2022 at 8:01 AM Remi Forax  wrote:

> 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" 
> > To: "core-libs-dev" 
> > 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 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
>


Re: Should System.exit be controlled by a Scope Local?

2022-02-27 Thread Remi Forax
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" 
> To: "core-libs-dev" 
> 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 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


Should System.exit be controlled by a Scope Local?

2022-02-26 Thread Ethan McCue
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 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