Java 21 introduces (as a preview) support for instance main methods and for main methods (static or instance) that have no parameters:

Selecting a main method

When launching a class, the launch protocol chooses the first of the following methods to invoke: - A static void main(String[] args) method of non-private access (i.e., public, protected or package) declared in the launched class, - A static void main() method of non-private access declared in the launched class, - A void main(String[] args) instance method of non-private access declared in the launched class or inherited from a superclass, or, finally, - A void main() instance method of non-private access declared in the launched class or inherited from a superclass.

To support these new main methods, some changes will be required in Boot:

  • MainClassFinder, as used by our Maven and Gradle plugins (and Antlib), only looks for public static void main(String[] args) methods at the moment
  • MainMethodRunner, as used by our launchers, only supports running a static main(String[]) method at the moment
  • DevTools ( see MainMethod), only supports static main(String[]) methods when finding the method to use for restart at the moment

Comment From: rafaelrc7

Hello, is this issue available for work?

Comment From: wilkinsona

Thanks for the offer, @rafaelrc7, but not yet. We haven't decided when to schedule this. As the support is only in preview at the moment, we may wait for it to be delivered in its final form before doing anything.

Comment From: wilkinsona

https://openjdk.org/jeps/512 is tracking the JDK change where they currently expect it to be finalised in Java 25 which should GA in September. If this comes to pass, we could consider this in 4.0.x which will GA in November.

Comment From: joshlong

I feel like the issue's a bit more involved, because you don't even need to define a class.

void main(){ 
  IO.println("hi"); 
}

is a valid java program.

what would we even pass to SpringApplication.run(Class<T>, args)?

Maybe we could support something like the following, and somehow determine that this is a special implicit class and treat it as though it were annotated with @SpringBootApplication

void main(){ 
 SpringApplication.run(this);
}

or

void main(String args[]){ 
 SpringApplication.run(this,args);
}

also, what about the class path? in the groovy support for spring run, we had @Grab. in java, having a pom.xml and a whole src/{test,main}/{resources,java} tree feels like it'd defeat the intrinsic lightweight script-y feel enabled by this feature.

I wish start.spring.io had an option to generate a run.{sh,bat} that somehow downloaded the right dependencies and put them on the class path if they weren't already there, like the light jars @dsyer built some years ago.

so the deliverable would just be run.sh and a Main.java. or, maybe

Comment From: joshlong

whatever work we did would also help with using Kotlin scripts and spring boot, too