Re: RFR: 8282008: Incorrect handling of quoted arguments in ProcessBuilder [v3]

2022-02-27 Thread Maxim Kartashev
On Fri, 18 Feb 2022 17:21:48 GMT, Olga Mikhaltsova  
wrote:

>> This fix made equal processing of strings such as ""C:\\Program 
>> Files\\Git\\"" before and after JDK-8250568.
>> 
>> For example, it's needed to execute the following command on Windows:
>> `C:\Windows\SysWOW64\WScript.exe "MyVB.vbs" "C:\Program Files\Git" "Test"`
>> it's equal to:
>> `new ProcessBuilder("C:\\Windows\\SysWOW64\\WScript.exe", "MyVB.vbs", 
>> ""C:\\Program Files\\Git\\"", "Test").start();`
>> 
>> While processing, the 3rd argument ""C:\\Program Files\\Git\\"" treated as 
>> unquoted due to the condition added in JDK-8250568.
>> 
>> private static String unQuote(String str) {
>> .. 
>>if (str.endsWith("\\"")) {
>> return str;// not properly quoted, treat as unquoted
>> }
>> ..
>> }
>> 
>> 
>> that leads to the additional surrounding by quotes in 
>> ProcessImpl::createCommandLine(..) because needsEscaping(..) returns true 
>> due to the space inside the string argument.
>> As a result the native function CreateProcessW 
>> (src/java.base/windows/native/libjava/ProcessImpl_md.c) gets the incorrectly 
>> quoted argument: 
>> 
>> pcmd = C:\Windows\SysWOW64\WScript.exe MyVB.vbs ""C:\Program Files\Git"" Test
>> (jdk.lang.Process.allowAmbiguousCommands = true)
>> pcmd = "C:\Windows\SysWOW64\WScript.exe" MyVB.vbs ""C:\Program Files\Git\\"" 
>> Test
>> (jdk.lang.Process.allowAmbiguousCommands = false)
>> 
>> 
>> Obviously, a string ending with `"\\""` must not be started with `"""` to 
>> treat as unquoted overwise it’s should be treated as properly quoted.
>
> Olga Mikhaltsova has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Add a new line to the end of test file for JDK-8282008

Actually, this change should be made even more generic because the string might 
end with any even number of the backslash characters followed by a 
free-standing quote, in which case additional quoting should not be required.

-

PR: https://git.openjdk.java.net/jdk/pull/7504


Re: RFR: 8275731: CDS archived enums objects are recreated at runtime [v7]

2022-02-27 Thread Ioi Lam
> **Background:**
> 
> In the Java Language, Enums can be tested for equality, so the constants in 
> an Enum type must be unique. Javac compiles an enum declaration like this:
> 
> 
> public enum Day {  SUNDAY, MONDAY ... } 
> 
> 
> to
> 
> 
> public class Day extends java.lang.Enum {
> public static final SUNDAY = new Day("SUNDAY");
> public static final MONDAY = new Day("MONDAY"); ...
> }
> 
> 
> With CDS archived heap objects, `Day::` is executed twice: once 
> during `java -Xshare:dump`, and once during normal JVM execution. If the 
> archived heap objects references one of the Enum constants created at dump 
> time, we will violate the uniqueness requirements of the Enum constants at 
> runtime. See the test case in the description of 
> [JDK-8275731](https://bugs.openjdk.java.net/browse/JDK-8275731)
> 
> **Fix:**
> 
> During -Xshare:dump, if we discovered that an Enum constant of type X is 
> archived, we archive all constants of type X. At Runtime, type X will skip 
> the normal execution of `X::`. Instead, we run 
> `HeapShared::initialize_enum_klass()` to retrieve all the constants of X that 
> were saved at dump time.
> 
> This is safe as we know that `X::` has no observable side effect -- 
> it only creates the constants of type X, as well as the synthetic value 
> `X::$VALUES`, which cannot be observed until X is fully initialized.
> 
> **Verification:**
> 
> To avoid future problems, I added a new tool, CDSHeapVerifier, to look for 
> similar problems where the archived heap objects reference a static field 
> that may be recreated at runtime. There are some manual steps involved, but I 
> analyzed the potential problems found by the tool are they are all safe 
> (after the current bug is fixed). See cdsHeapVerifier.cpp for gory details. 
> An example trace of this tool can be found at 
> https://bugs.openjdk.java.net/secure/attachment/97242/enum_warning.txt
> 
> **Testing:**
> 
> Passed Oracle CI tiers 1-4. WIll run tier 5 as well.

Ioi Lam has updated the pull request with a new target base due to a merge or a 
rebase. The pull request now contains 10 commits:

 - fixed copyright year
 - Merge branch 'master' into 8275731-heapshared-enum
 - fixed whitespace
 - Fixed comments per @calvinccheung review
 - Merge branch 'master' into 8275731-heapshared-enum
 - Use InstanceKlass::do_local_static_fields for some field iterations
 - Merge branch 'master' into 8275731-heapshared-enum
 - added exclusions needed by "java -Xshare:dump -ea -esa"
 - Comments from @calvinccheung off-line
 - 8275731: CDS archived enums objects are recreated at runtime

-

Changes: https://git.openjdk.java.net/jdk/pull/6653/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk=6653=06
  Stats: 860 lines in 16 files changed: 807 ins; 4 del; 49 mod
  Patch: https://git.openjdk.java.net/jdk/pull/6653.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/6653/head:pull/6653

PR: https://git.openjdk.java.net/jdk/pull/6653


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  > > 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" mailto:et...@mccue.dev
> >>
> >  > 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 

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 > 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
 > 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();
 >
 >         ...
 >
 >         

Re: RFR: JDK-8282144 RandomSupport.convertSeedBytesToLongs sign extension overwrites previous bytes

2022-02-27 Thread Jim Laskey
On Fri, 25 Feb 2022 19:58:13 GMT, Brian Burkhalter  wrote:

>> Class: ./java.base/share/classes/jdk/internal/util/random/RandomSupport.java 
>> Method: public static long[] convertSeedBytesToLongs(byte[] seed, int n, int 
>> z) 
>> 
>> The method attempts to create an array of longs by consuming the input bytes 
>> most significant bit first. New bytes are appended to the existing long 
>> using the OR operator on the signed byte. Due to sign extension this will 
>> overwrite all the existing bits from 63 to 8 if the next byte is negative.
>
> test/jdk/java/util/Random/T8282144.java line 39:
> 
>> 37: public class T8282144 {
>> 38: public static void main(String[] args) {
>> 39: RandomGenerator rng = 
>> RandomGeneratorFactory.of("L64X128MixRandom").create(42);
> 
> Does `rng` always produce the same sequence? If so, then perhaps the seed, 
> `42`, should be a random value that is printed.

42 was chosen because its is known to produce negative byte values, other 
random values might not.

> test/jdk/java/util/Random/T8282144.java line 52:
> 
>> 50: for (int k = 0; k < existing.length; k++) {
>> 51: if (existing[k] != testing[k]) {
>> 52: throw new 
>> RuntimeException("convertSeedBytesToLongs incorrect");
> 
> Should `i`, `j`, and `k` be included in the exception message?

Correctness is binary - either it works or it doesn't. The values of i, j, k 
would not assist in isolating issues.

-

PR: https://git.openjdk.java.net/jdk/pull/7614


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

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.overridingOut(out, () -> {
 

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

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