On Mon, 15 Apr 2024 07:36:05 GMT, Jan Lahoda <jlah...@openjdk.org> wrote:
>> 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: > > Reflecting review feedback. Does this also fix [JDK-8329581](https://bugs.openjdk.org/browse/JDK-8329581)? ------------- PR Comment: https://git.openjdk.org/jdk/pull/18753#issuecomment-2057206293