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

>> Consider these classes:
>> 
>> package p;
>> public class Lib {
>>     void main(String... args) {
>>         System.err.println("Lib!");
>>     }
>> }
>> 
>> and:
>> 
>> import p.Lib;
>> public class Main extends Lib {
>>     public void main() {
>>         System.err.println("Main!");
>>     }
>> }
>> 
>> 
>> Note the classes are in different packages. Running this on JDK 26 yields:
>> 
>> $ jdk-26/bin/java Main.java
>> Lib!
>> 
>> 
>> that is not correct - the method `Lib.main(String[])` is package private, 
>> and is not inherited to `Main`, i.e. not a member of `Main`, and hence the 
>> launcher should not use it. The launcher should only inspect methods that 
>> are members (direct or inherited) of `Main`.
>> 
>> This PR fixes that by only using package-private methods in they are 
>> declared in the same class as is the main class. Testing is enhanced to 
>> cover all related cases I/we were able to find.
>> 
>> Also please review the corresponding CSR:
>> https://bugs.openjdk.org/browse/JDK-8378555
>
> 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?

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

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

Reply via email to