RFR: 8357016: Candidate main methods not computed properly
Jan Lahoda
jlahoda at openjdk.org
Fri May 16 11:06:53 UTC 2025
On Fri, 16 May 2025 10:10:17 GMT, Jaikiran Pai <jpai at openjdk.org> wrote:
>> A consider class like this:
>>
>>
>> public class TwoMains {
>> private static void main(String... args) {}
>> static void main() {
>> System.out.println("Should be called, but is not.");
>> }
>> }
>>
>>
>> The `MethodFinder` will do lookup for the `main(String[])` method, and it finds one, so does not proceed with a lookup for `main()`. But then, it will check the access modifier, and will reject that method, never going back to the `main()` method. This is not what the JLS says about the lookup - the private method is not a candidate, and should be ignored.
>>
>> Something similar happens if the return type is not `void`.
>>
>> This PR is fixing that by checking whether the `main(String[])` method is usable early, and falling back to `main()` if it `main(String[])` is not usable.
>>
>> It also removes the check for the `abstract` method, as that, by itself, is not really backed by JLS, but adds a check for `abstract` class, producing a user-friendly message is trying to invoke an instance `main` method on an `abstract` class (which, obviously, cannot be instantiated).
>
> src/java.base/share/classes/sun/launcher/resources/launcher.properties line 283:
>
>> 281: make inner class static or move inner class out to separate source file
>> 282: java.launcher.cls.error8=\
>> 283: Error: abstract class {0} can not instantiated\n\
>
> Nit - should this use a comma instead of the newline?
The other errors here provide some advice on the second line, so I kept that pattern for this error as well. So, the newline is intentional.
> src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher.properties line 113:
>
>> 111: # 0: string
>> 112: launcher.err.cant.find.main.method=\
>> 113: can''t find main(String[]) or main() method in class: {0}
>
> Out of curiosity, why the double single quotes? I see it being used in other messages in this file as well, so it doesn't seem to be a typo.
Pieces of text in `MessageFormat` can be quoted using `'...'`. So, a single `'` does not work, as that is considered to be part of quoting. Using `''` escapes that behavior.
> test/jdk/tools/launcher/Arrrghs.java line 635:
>
>> 633: tr.contains("Error: abstract class Foo can not instantiated");
>> 634: if (!tr.testStatus)
>> 635: System.out.println(tr);
>
> Hello Jan, I think this is pre-existing, but it looks like we don't fail the test even when `tr.testStatus` indicates a failure? We seem to only write out to `System.out` and return from the test method. Am I misreading the test code?
`tr.contains` marks the test as failing, and eventually `TestHelper.main` will fail the test. It is probably not how I would write the test from scratch, but re-writing an already existing test also does not seem like a good option.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/25256#discussion_r2092836696
PR Review Comment: https://git.openjdk.org/jdk/pull/25256#discussion_r2092838074
PR Review Comment: https://git.openjdk.org/jdk/pull/25256#discussion_r2092835532
More information about the core-libs-dev
mailing list