> 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 one additional commit since the last revision: Fixing typo (should not continue after an exception from a constructor). ------------- Changes: - all: https://git.openjdk.org/jdk/pull/18753/files - new: https://git.openjdk.org/jdk/pull/18753/files/c007f61e..aadfb380 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=18753&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=18753&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 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