> Consider code like:
> 
> public class MainClass {
>     public MainClass() {
>         System.out.println("Constructor called!");
>     }
>     public static void main() {
>         System.out.println("main called!");
>     }
> }
> 
> and compile and run it, with preview enabled, like:
> 
> $ javac /tmp/MainClass.java 
> $ java --enable-preview -classpath /tmp MainClass
> Constructor called!
> main called!
> 
> 
> That is wrong, as the `main` method is static, and there is no need to create 
> a new instance of the class.
> 
> The reason is that as launcher attempts to invoke the main method, it goes in 
> the following order: 1) static-main-with-args; 2) instance-main-with-args; 3) 
> static-main-without-args; 4) instance-main-without-args. But, for the 
> instance variants, the code first creates a new instance of the given class, 
> and only then attempts to lookup the `main` method, and will pass to the next 
> option when the `main` method lookup fails. So, when invoking 
> static-main-without-args, the current class instance may be created for 
> instance-main-with-args, which will then fail due to the missing 
> `main(String[])` method.
> 
> The proposed solution to this problem is to simply first do a lookup for the 
> `main` method (skipping to the next variant when the given main method does 
> not exist, without instantiating the current class).
> 
> There is also a relatively closely related problem: what happens when the 
> constructor throws an exception?
> 
> public class MainClass {
>     public MainClass() {
>         if (true) throw new RuntimeException();
>     }
>     public void main() {
>         System.out.println("main called!");
>     }
> }
> 
> 
> when compiled an run, this produces no output whatsoever:
> 
> $ javac /tmp/MainClass.java 
> $ java --enable-preview -classpath /tmp MainClass
> $
> 
> 
> This is because any exceptions thrown from the constructor are effectively 
> ignored, and the launcher will continue with the next variant. This seems 
> wrong - the exception should be printed for the user, like:
> 
> $ java --enable-preview -classpath /tmp/ MainClass 
> Exception in thread "main" java.lang.RuntimeException
>         at MainClass.<init>(MainClass.java:3)
> 
> 
> This patch proposes to do that by not consuming the exceptions thrown from 
> the constructor, and stop the propagation to the next variant.

Jan Lahoda has updated the pull request incrementally with three additional 
commits since the last revision:

 - Reflecting code formatting suggestion.
 - First lookup the main method, and only then the constructor.
 - Attempting to solve JDK-8329581 by only ignoring j.l.NoSuchMethodError

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/18753/files
  - new: https://git.openjdk.org/jdk/pull/18753/files/2022aa5a..c007f61e

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=18753&range=02
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=18753&range=01-02

  Stats: 117 lines in 2 files changed: 73 ins; 5 del; 39 mod
  Patch: https://git.openjdk.org/jdk/pull/18753.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/18753/head:pull/18753

PR: https://git.openjdk.org/jdk/pull/18753

Reply via email to