Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8351188

java launcher's implementation of (instance) main method selection can cause unexpected classloading failures

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • 25
    • 23
    • tools
    • None

      Consider the following two trivial java files:

      Foo.java:

          public class Foo {
              public static void main(final String[] args) throws Exception {
                  System.out.println("hello world");
              }

              // never invoked or referenced (dead) code
              private SomeNonExistentRuntimeType doNothing() throws Exception {
                  return null;
              }
          }

      SomeNonExistentRuntimeType.java:

      public class SomeNonExistentRuntimeType {

      }

      Compile them as follows:

      javac Foo.java SomeNonExistentRuntimeType.java

      Now delete (only) the compiled SomeNonExistentRuntimeType.class file to simulate the case where that class is missing at runtime (in the classpath).

      Now run:

      java Foo

      This will rightly print:

      hello world

      and the program exits normally. Now, using a JDK which has "Instance Main Methods" preview feature, like JDK 23, 24 or mainline, --enable-preview and run the same program again:

      java --enable-preview Foo

      This results in the application failing to launch with the following exception:

      Error: Unable to initialize main class Foo
      Caused by: java.lang.NoClassDefFoundError: SomeNonExistentRuntimeType

      This is due to the current implementation of the launcher where, to support JEP-495 https://openjdk.org/jeps/495, it tries to identify potential "main" methods and while doing so it ends up using the existing reflection based infrastructure where it iterates over each method of the main class and tries to resolve the types of the method params and return types, thus resulting in additional classloading and potential classloading failures of non-existent types (that may be unused by the application at runtime).

      I think the launcher's implementation can be changed to minimize the methods it looks for (it just needs to look for methods named "main") and only resolve the referenced types if that "main" method is determined as the one to invoke.

            cstein Christian Stein
            jpai Jaikiran Pai
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: