On Thu, 19 Mar 2026 14:43:00 GMT, Jaikiran Pai <[email protected]> wrote:

>> src/java.base/share/classes/jdk/internal/misc/MethodFinder.java line 102:
>> 
>>> 100:     }
>>> 101: 
>>> 102:     private static boolean isValidMainMethod(Class<?> initialClass, 
>>> Method mainMethodCandidate) {
>> 
>> The `mainMethodCandidate` that gets passed here is sourced from a call to 
>> `JavaLangAccess.findMethod(...)`. As far as I can see, the implementation of 
>> that `findMethod()` could return an `abstract` or `native` method named 
>> `main(...)`. Should additional checks be added here in `isValidMainMethod()` 
>> to skip such methods?
>> 
>> Of course, this isn't due the change you have done here and it's 
>> pre-existing code. So it brings up the question whether we currently don't 
>> have tests to verify that such unexpected main methods don't get prefered in 
>> this implementation (and then fail to launch).
>
> I just gave this a try against Java 26:
> 
> 
> public class BaseClass {
>       public void main() {
>               System.out.println("hello from " + BaseClass.class);
>       }
> }
> 
> 
> 
> public class ChildClass extends BaseClass {
>       public native void main();
> }
> 
> 
> Then compiled them:
> 
> 
> javac BaseClass.java ChildClass.java
> 
> 
> and launched the `ChildClass`:
> 
> 
> java ChildClass
> 
> This fails with:
> 
> 
> Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void 
> ChildClass.main()'
>       at ChildClass.main(Native Method)
> 
> 
> which I think is wrong, and instead the `java` launcher should have picked up 
> `BaseClass.main()` as the main entry point?

Thanks for the comment. First, let me point out that the `main` method 
selection is not up to the launcher to decide. The selection process is 
specified by the JLS:
https://docs.oracle.com/javase/specs/jls/se26/html/jls-12.html#jls-12.1.4
and the specification to my knowledge says nothing about `native` or `abstract` 
in terms of selection.

Specifically for `native`, I don't see why the selection should ignore `native` 
methods. Those can be invoked (provided the native library is correctly linked 
in, of course). Additionally, note that in your example, the method 
`BaseClass.main()` is not even a member of `ChildClass`, as `ChildClass` 
overrides the method, making it even more difficult to call `BaseClass.main()` 
in context of `ChildClass`.

For `abstract`, admittedly, the selection process may select an abstract 
method, while there may be an alternative static method it could call, like 
here:

$ cat /tmp/M.java 
public abstract class M {
    abstract void main(String... args);
    static void main() {
        System.err.println("Hello!");
    }
}
$ javac /tmp/M.java 
$ java -classpath /tmp/ M
Error: abstract class M can not be instantiated
please use a concrete class


But, I think this is very consistent with what the JLS is saying about the 
selection. Discussion on whether the selection process in JLS should be 
different is possible, but an implementation PR is not the best venue for it.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/30221#discussion_r2960757054

Reply via email to