Re: JPMS Access Checks, Verification and the Security Manager

2017-06-02 Thread Volker Simonis
Thanks Alex,

that makes sense.

Regards,
Volker


On Fri, Jun 2, 2017 at 2:13 AM, Alex Buckley  wrote:
> On 5/24/2017 12:13 AM, Volker Simonis wrote:
>>
>> OK, so from what you say I understand that the verification errors I
>> see with the Security Manager enabled are an implementation detail of
>> HotSpot (because verification uses the same class loading mechanism
>> like the runtime) which is not required but still acceptable under the
>> JVMS. Is that correct?
>
>
> The JVMS is precise about which exceptions are allowed to be thrown by a JVM
> implementation during verification, and AccessControlException is not one of
> them. However, the JVMS is only one part of the Java SE Platform
> Specification. It is quite proper if another part specifies an
> AccessControlException when a class in a restricted package is referenced by
> a class without permission.
>
> I'm thinking in particular of the API specification for
> SecurityManager::checkPackageAccess. It states, "This method is called by
> the loadClass method of class loaders." Plainly, the intention is that a
> class (Tricky) which initiates the loading of another class
> (com.sun.crypto.provider.SunJCE) can do so only if it has permission to
> reference the other class. Unfortunately, the statement as written is only
> guaranteed to be true for the built-in class loaders of the Java SE Platform
> and not for user-defined class loaders. Accordingly, we will update the API
> specification to clarify how a JVM implementation may support the Security
> Manager in checking permissions when classes are loaded and resolved. But to
> answer your original question, an application CAN fail because the verifier
> can't load classes due to Security Manager restrictions; you may have to
> grant additional permissions if application classes wish to reference
> certain JDK 9 packages.
>
> Alex


Re: JPMS Access Checks, Verification and the Security Manager

2017-06-01 Thread Alex Buckley

On 5/24/2017 12:13 AM, Volker Simonis wrote:

OK, so from what you say I understand that the verification errors I
see with the Security Manager enabled are an implementation detail of
HotSpot (because verification uses the same class loading mechanism
like the runtime) which is not required but still acceptable under the
JVMS. Is that correct?


The JVMS is precise about which exceptions are allowed to be thrown by a 
JVM implementation during verification, and AccessControlException is 
not one of them. However, the JVMS is only one part of the Java SE 
Platform Specification. It is quite proper if another part specifies an 
AccessControlException when a class in a restricted package is 
referenced by a class without permission.


I'm thinking in particular of the API specification for 
SecurityManager::checkPackageAccess. It states, "This method is called 
by the loadClass method of class loaders." Plainly, the intention is 
that a class (Tricky) which initiates the loading of another class 
(com.sun.crypto.provider.SunJCE) can do so only if it has permission to 
reference the other class. Unfortunately, the statement as written is 
only guaranteed to be true for the built-in class loaders of the Java SE 
Platform and not for user-defined class loaders. Accordingly, we will 
update the API specification to clarify how a JVM implementation may 
support the Security Manager in checking permissions when classes are 
loaded and resolved. But to answer your original question, an 
application CAN fail because the verifier can't load classes due to 
Security Manager restrictions; you may have to grant additional 
permissions if application classes wish to reference certain JDK 9 packages.


Alex


Re: JPMS Access Checks, Verification and the Security Manager

2017-05-24 Thread Volker Simonis
On Tue, May 23, 2017 at 10:01 PM, Alex Buckley  wrote:
> On 5/23/2017 7:44 AM, Volker Simonis wrote:
>>
>> So maybe I rephrase my question a little more generally:
>>
>> Is it required for the verifier to do security and/or access checks
>> during the verification phase or could/should these checks be
>> postponed to runtime? The issue with verification errors due to
>> missing classes from Remi's previous answer is probably a corner case
>> of this question.
>
>
> Verification must perform class loading in order to check subtyping, but
> verification does not check access to the loaded classes. To be precise,
> verification in JVMS 4.10.1 does not appeal to class resolution (JVMS
> 5.4.3.1) nor to access control (JVMS 5.4.4). Nor does verification in JVMS
> 4.10.1 know what the package.access file is.
>
> What you are seeing when the Security Manager is enabled is that class
> loading fails (due to a package.access check in Hotspot) and so verification
> fails. The verifier is not performing the package.access check per se.
>

OK, so from what you say I understand that the verification errors I
see with the Security Manager enabled are an implementation detail of
HotSpot (because verification uses the same class loading mechanism
like the runtime) which is not required but still acceptable under the
JVMS. Is that correct?

Thanks,
Volker

> Alex


Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread David Holmes

On 23/05/2017 10:45 PM, Volker Simonis wrote:

On Tue, May 23, 2017 at 10:51 AM, David Holmes  wrote:

On 23/05/2017 6:20 PM, Alan Bateman wrote:


Volker - one suggestion for your experiments is to change your JDK 8
security properties file (java.security) to add "com.sun.crypto.provider."
to the value of the "package.access" property. That should mean you will get
the same AccessControlException with JDK 8 as you do with JDK 9. It may help
to reason about the JDK 8 behavior, including what is triggered by
verification, before looking at 9.

On the "Error: A JNI error has occurred, please check your installation
and try again" message. It's not core to your questions of course but I
agree it is confusing. Ramanand Patil had a number of attempts on
core-libs-dev to improve this and it may be that more is needed there.



Yes I was sure we had agreed to remove that and I don't see it in Oracle JDK
so perhaps it is only in OpenJDK launcher?



Hi David,

not sure what you mean? Does the Oracle JDK come with another launcher
compared to the OpenJDK?


No - I was confusing myself.


I've just tried with the latest EA build 170 (which I assume is an
Oracle JDK) and I see exactly the same error:


Ok. I see now that we still have the confusing error message depending 
on exactly when the exception is thrown.


David
-



java -Djava.security.manager -showversion Tricky ""
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+170)
Java HotSpot(TM) Server VM (build 9-ea+170, mixed mode)
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.security.AccessControlException:
access denied ("java.lang.RuntimePermission"
"accessClassInPackage.com.sun.crypto.provider")
 at 
java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:471)
 at 
java.base/java.security.AccessController.checkPermission(AccessController.java:894)
 at 
java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:561)
 at 
java.base/java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1534)
 at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:671)
 at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:669)
 at java.base/java.security.AccessController.doPrivileged(Native Method)
 at java.base/java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:669)
 at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
 at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3134)
 at java.base/java.lang.Class.getMethodsRecursive(Class.java:3275)
 at java.base/java.lang.Class.getMethod0(Class.java:3261)
 at java.base/java.lang.Class.getMethod(Class.java:2062)
 at 
java.base/sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:712)
 at 
java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:570)

So what do you mean when saying that you don't see it in the Oracle JDK?

Regards,
Volker


David



-Alan





Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Alex Buckley

On 5/23/2017 7:44 AM, Volker Simonis wrote:

So maybe I rephrase my question a little more generally:

Is it required for the verifier to do security and/or access checks
during the verification phase or could/should these checks be
postponed to runtime? The issue with verification errors due to
missing classes from Remi's previous answer is probably a corner case
of this question.


Verification must perform class loading in order to check subtyping, but 
verification does not check access to the loaded classes. To be precise, 
verification in JVMS 4.10.1 does not appeal to class resolution (JVMS 
5.4.3.1) nor to access control (JVMS 5.4.4). Nor does verification in 
JVMS 4.10.1 know what the package.access file is.


What you are seeing when the Security Manager is enabled is that class 
loading fails (due to a package.access check in Hotspot) and so 
verification fails. The verifier is not performing the package.access 
check per se.


Alex


Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Sean Mullan

On 5/23/17 10:44 AM, Volker Simonis wrote:

The other question is if '--add-exports' should implicitly grant the
corresponding security permissions? I understand that package/class
visibility and security checks are somewhat orthogonal concepts so I
tend to agree with the current functionality (and a part of this
problem is now tracked by JDK-8174766). Nevertheless it is probably
wise to document these differences so people won't get surprised.


We considered it but the SecurityManager checks all callers (and not 
just the target module) on the stack for the appropriate 
accessClassInPackage RuntimePermission. Also, 
SecurityManager.checkPackageAccess does not know what the target module 
is, all it has is the package name. It is possible however that we could 
respect the module access rights when loading classes in the internal 
ClassLoader.checkPackageAccess method. I will be looking more into this 
in the JDK 10 timeframe.


The current javadoc of SecurityManager.checkPackageAccess [1] does 
document this behavior:


"This implementation also restricts all non-exported packages of modules 
loaded by the platform class loader or its ancestors. A "non-exported 
package" refers to a package that is not exported to all modules. 
Specifically, it refers to a package that either is not exported at all 
by its containing module or is exported in a qualified fashion by its 
containing module."


--Sean

[1] 
http://download.java.net/java/jdk9/docs/api/java/lang/SecurityManager.html#checkPackageAccess-java.lang.String-




Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Volker Simonis
On Tue, May 23, 2017 at 10:20 AM, Alan Bateman  wrote:
> Volker - one suggestion for your experiments is to change your JDK 8
> security properties file (java.security) to add "com.sun.crypto.provider."
> to the value of the "package.access" property. That should mean you will get
> the same AccessControlException with JDK 8 as you do with JDK 9. It may help
> to reason about the JDK 8 behavior, including what is triggered by
> verification, before looking at 9.
>

You're right. JDK 8 produces the same error if we add
"com.sun.crypto.provider." to the value of the "package.access"
property. I didn't wanted to blame jdk9 here - I just saw this
difference because "com.sun.crypto.provider." isn't contained in the
"package.access" property by default.

So maybe I rephrase my question a little more generally:

Is it required for the verifier to do security and/or access checks
during the verification phase or could/should these checks be
postponed to runtime? The issue with verification errors due to
missing classes from Remi's previous answer is probably a corner case
of this question.

The other question is if '--add-exports' should implicitly grant the
corresponding security permissions? I understand that package/class
visibility and security checks are somewhat orthogonal concepts so I
tend to agree with the current functionality (and a part of this
problem is now tracked by JDK-8174766). Nevertheless it is probably
wise to document these differences so people won't get surprised.

> On the "Error: A JNI error has occurred, please check your installation and
> try again" message. It's not core to your questions of course but I agree it
> is confusing. Ramanand Patil had a number of attempts on core-libs-dev to
> improve this and it may be that more is needed there.
>

Yes, a better error message would be nice but thats a different question.

Thanks,
Volker

> -Alan
>


Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Volker Simonis
On Tue, May 23, 2017 at 10:51 AM, David Holmes  wrote:
> On 23/05/2017 6:20 PM, Alan Bateman wrote:
>>
>> Volker - one suggestion for your experiments is to change your JDK 8
>> security properties file (java.security) to add "com.sun.crypto.provider."
>> to the value of the "package.access" property. That should mean you will get
>> the same AccessControlException with JDK 8 as you do with JDK 9. It may help
>> to reason about the JDK 8 behavior, including what is triggered by
>> verification, before looking at 9.
>>
>> On the "Error: A JNI error has occurred, please check your installation
>> and try again" message. It's not core to your questions of course but I
>> agree it is confusing. Ramanand Patil had a number of attempts on
>> core-libs-dev to improve this and it may be that more is needed there.
>
>
> Yes I was sure we had agreed to remove that and I don't see it in Oracle JDK
> so perhaps it is only in OpenJDK launcher?
>

Hi David,

not sure what you mean? Does the Oracle JDK come with another launcher
compared to the OpenJDK?

I've just tried with the latest EA build 170 (which I assume is an
Oracle JDK) and I see exactly the same error:

java -Djava.security.manager -showversion Tricky ""
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+170)
Java HotSpot(TM) Server VM (build 9-ea+170, mixed mode)
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.security.AccessControlException:
access denied ("java.lang.RuntimePermission"
"accessClassInPackage.com.sun.crypto.provider")
at 
java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:471)
at 
java.base/java.security.AccessController.checkPermission(AccessController.java:894)
at 
java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:561)
at 
java.base/java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1534)
at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:671)
at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:669)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:669)
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3134)
at java.base/java.lang.Class.getMethodsRecursive(Class.java:3275)
at java.base/java.lang.Class.getMethod0(Class.java:3261)
at java.base/java.lang.Class.getMethod(Class.java:2062)
at 
java.base/sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:712)
at 
java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:570)

So what do you mean when saying that you don't see it in the Oracle JDK?

Regards,
Volker

> David
>
>
>> -Alan
>>
>


Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread David Holmes

On 23/05/2017 6:20 PM, Alan Bateman wrote:
Volker - one suggestion for your experiments is to change your JDK 8 
security properties file (java.security) to add 
"com.sun.crypto.provider." to the value of the "package.access" 
property. That should mean you will get the same AccessControlException 
with JDK 8 as you do with JDK 9. It may help to reason about the JDK 8 
behavior, including what is triggered by verification, before looking at 9.


On the "Error: A JNI error has occurred, please check your installation 
and try again" message. It's not core to your questions of course but I 
agree it is confusing. Ramanand Patil had a number of attempts on 
core-libs-dev to improve this and it may be that more is needed there.


Yes I was sure we had agreed to remove that and I don't see it in Oracle 
JDK so perhaps it is only in OpenJDK launcher?


David



-Alan



Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Alan Bateman
Volker - one suggestion for your experiments is to change your JDK 8 
security properties file (java.security) to add 
"com.sun.crypto.provider." to the value of the "package.access" 
property. That should mean you will get the same AccessControlException 
with JDK 8 as you do with JDK 9. It may help to reason about the JDK 8 
behavior, including what is triggered by verification, before looking at 9.


On the "Error: A JNI error has occurred, please check your installation 
and try again" message. It's not core to your questions of course but I 
agree it is confusing. Ramanand Patil had a number of attempts on 
core-libs-dev to improve this and it may be that more is needed there.


-Alan



Re: JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Remi Forax
Hi Volker,
this is the behavior of the verifier since 6 (when the split verifier becomes 
the default one).

Let say you have a code like this,

public class TestVerifier {
  static class B extends A { }
  static class A { }

  public static void main(String[] args) {
A a;
if (args.length == 0) {
  a = new A();
} else {
  a = new B();
}
System.out.println(a.toString());
  }
}

if you compile and then remove TestVerifier$B.class, you will get
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: TestVerifier$B
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at 
sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: TestVerifier$B
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more

whatever the comand line arguments because it's the verifier that throws an 
error. 

There is a workaround for you, if you use an interface instead of a class (in 
my example, make A an interface), it will work !
The verifier does not verify interface at verification time, the checks in done 
once by the VM at runtime.

so if there is a bug, it's in the way the verifier actually works i.e. if it 
can not find a class or do not see a class because of the module encapsulation, 
it should postpone the check at runtime instead of reporting an error at 
compile time. Thats said, i'm not sure it's a good idea.

cheers,
Rémi

- Mail original -
> De: "Volker Simonis" 
> À: "jigsaw-dev" , "security-dev" 
> 
> Envoyé: Mardi 23 Mai 2017 09:27:22
> Objet: JPMS Access Checks, Verification and the Security Manager

> Hi,
> 
> my question is if it is OK for a program which otherwise runs fine to
> fail during class verification if running with a security manager
> because of module access restrictions?
> 
> As the following write-up got a little lengthy, I've also uploaded a
> html version for a nicer reading experience :)
> 
> http://cr.openjdk.java.net/~simonis/webrevs/2017/veri_with_secman/sm.html
> 
> Consider the following small, self-contained program which statically
> references com.sun.crypto.provider.SunJCE:
> 
> import java.security.Provider;
> import com.sun.crypto.provider.SunJCE;
> 
> public class Tricky {
> 
>  public static void main(String args[]) throws Exception {
>try {
>  System.out.println(Tricky.class + " (" +
> Tricky.class.getClassLoader() + ")" + args[0]);
>}
>catch (Exception e) {
>  Provider p = new SunJCE();
>  System.out.println(p + " (" + p.toString() + ")");
>}
>  }
> }
> 
> This program easily compiles and runs with Oracle/OpenJDK 8:
> 
> $ javac Tricky
> $ java Tricky ""
> class Tricky (sun.misc.Launcher$AppClassLoader@4e0e2f2a)
> $ java Tricky
> SunJCE version 1.8 (SunJCE version 1.8)
> 
> The second invocation (without argument) will cause an exception (when
> trying to access the first element of the zero length argument array
> at 'args[0]') which will be caught in the exception handler where we
> create a new 'SunJCE' object and print its string representation to
> stdout. The first invocation (with an empty argument) doesn't provoke
> an exception and will just print the class itself together with its
> class loader.
> 
> When we run the same (jdk8 compiled) program with jdk9, we'll see the
> following result:
> 
> $ jdk9/java Tricky ""
> class Tricky (jdk.internal.loader.ClassLoaders$AppClassLoader@ba8a1dc)
> $ jdk9/java Tricky
> Exception in thread "main" java.lang.IllegalAccessError: class Tricky
> (in unnamed module @0x3b192d32) cannot access class
> com.sun.crypto.provider.SunJCE (in module java.base) because module
> java.base does not export com.sun.crypto.provider to unnamed module
> @0x3b192d32
>  at Tricky.main(Tricky.java:11)
> $ jdk9/java --add-exports java.base/com.sun.crypto.provider=ALL-UNNAMED Tricky
> SunJCE version 9 (SunJCE version 9)
> 
> The first invocation (with an empty argument) still works because we
> have lazy class loading a

JPMS Access Checks, Verification and the Security Manager

2017-05-23 Thread Volker Simonis
Hi,

my question is if it is OK for a program which otherwise runs fine to
fail during class verification if running with a security manager
because of module access restrictions?

As the following write-up got a little lengthy, I've also uploaded a
html version for a nicer reading experience :)

http://cr.openjdk.java.net/~simonis/webrevs/2017/veri_with_secman/sm.html

Consider the following small, self-contained program which statically
references com.sun.crypto.provider.SunJCE:

import java.security.Provider;
import com.sun.crypto.provider.SunJCE;

public class Tricky {

  public static void main(String args[]) throws Exception {
try {
  System.out.println(Tricky.class + " (" +
Tricky.class.getClassLoader() + ")" + args[0]);
}
catch (Exception e) {
  Provider p = new SunJCE();
  System.out.println(p + " (" + p.toString() + ")");
}
  }
}

This program easily compiles and runs with Oracle/OpenJDK 8:

$ javac Tricky
$ java Tricky ""
class Tricky (sun.misc.Launcher$AppClassLoader@4e0e2f2a)
$ java Tricky
SunJCE version 1.8 (SunJCE version 1.8)

The second invocation (without argument) will cause an exception (when
trying to access the first element of the zero length argument array
at 'args[0]') which will be caught in the exception handler where we
create a new 'SunJCE' object and print its string representation to
stdout. The first invocation (with an empty argument) doesn't provoke
an exception and will just print the class itself together with its
class loader.

When we run the same (jdk8 compiled) program with jdk9, we'll see the
following result:

$ jdk9/java Tricky ""
class Tricky (jdk.internal.loader.ClassLoaders$AppClassLoader@ba8a1dc)
$ jdk9/java Tricky
Exception in thread "main" java.lang.IllegalAccessError: class Tricky
(in unnamed module @0x3b192d32) cannot access class
com.sun.crypto.provider.SunJCE (in module java.base) because module
java.base does not export com.sun.crypto.provider to unnamed module
@0x3b192d32
  at Tricky.main(Tricky.java:11)
$ jdk9/java --add-exports java.base/com.sun.crypto.provider=ALL-UNNAMED Tricky
SunJCE version 9 (SunJCE version 9)

The first invocation (with an empty argument) still works because we
have lazy class loading and 'SunJCE' provider is actually never used.
The second invocation (without argument) obviously fails with jdk9
because 'java.base' doesn't export the package com.sun.crypto.provider
anymore. This can be fixed by adding '--add-exports
java.base/com.sun.crypto.provider=ALL-UNNAMED' to the command line as
demonstrated in the third invocation.

So far so good - everything worked as expected till now. Now let's run
the same program with the default security manager:

$ java -Djava.security.manager Tricky ""
class Tricky (sun.misc.Launcher$AppClassLoader@4e0e2f2a)
$ java -Djava.security.manager Tricky
SunJCE version 1.8 (SunJCE version 1.8)

The security manager doesn't change anything for jdk8! So let's try with jdk9:

$ jdk9/java -Djava.security.manager Tricky ""
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.security.AccessControlException:
access denied ("java.lang.RuntimePermission"
"accessClassInPackage.com.sun.crypto.provider")
at 
java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:471)
at 
java.base/java.security.AccessController.checkPermission(AccessController.java:894)
at 
java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:561)
at 
java.base/java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1534)
at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:671)
at java.base/java.lang.ClassLoader$1.run(ClassLoader.java:669)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at 
java.base/java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:669)
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3129)
at java.base/java.lang.Class.getMethodsRecursive(Class.java:3270)
at java.base/java.lang.Class.getMethod0(Class.java:3256)
at java.base/java.lang.Class.getMethod(Class.java:2057)
at 
java.base/sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:712)
at 
java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:570)

The first invocation (with an empty argument) crashes with a strange
JNI error. The call stack unveils that we haven't even entered the
main method of our program. Instead we've crashed in the jdk-internal
launcher 'sun.launcher.LauncherHelper' during 'checkAndLoadMain()'
with a 'java.security.AccessControlException' because we couldn't
access the 'com.sun.crypto.provider' package. That's strange because
we shouldn't need to load SunJCE provider for this invocation because
of lazy class loading.

A little reasoning and the