Spring Tutorial


I have played a bit with the Spring tutorial, mainly because I find the Application class definition/main method quite cumbersome and wanted to see if there was a better way to do that. I do understand all of it, so it is clear to me what each element does. It's just that it looks much more busy than I thought it should be.


public class Application {
    class object {
        platformStatic public fun main(args: Array<String>) {
            SpringApplication.run(javaClass<Application>(), *args)

vs. Java's

@ComponentScan @EnableAutoConfiguration public class Application {   static public void main(String[] args) {   SpringApplication.run(Application.class, args);   } }

I mean, this is terrible. Java's version is shorter and, I may dare to say, even prettier to look at. This is unacceptable to me :-) Kotlin is supposed to look much nicer than Java (it usually does!)

So, here are my attemps (which all failed horribly):

  1. There is no need for the main() method to be inside the Application class. That is just a Spring convention. So, let’s move it outside:

but then gradle fails with:

Execution failed for task ':findMainClass'. > Unable to find a single main class from the following candidates [_DefaultPackage, _DefaultPackage$Application$e0b08dc9]

So, apparently there's something wrong with using the default package.

  1. Fine let’s move it to com.example; it’s better, anyway.

> Unable to find a single main class from the following candidates [com.example.ExamplePackage, com.example.ExamplePackage$Application$05fdfa5c]

Nope, it's not working. So, let's inspect the first class with javap It is in fact defining a main() static method which, in turn, invokes another static method inside ExamplePackage$Application$05fdfa5c

  public static final void main(java.lang.String[]);   flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL   Code:tf8           Lorg/jetbrains/annotations/NotNull;   stack=1, locals=1, args_size=1le/ExamplePackage$Application$05fdfa5c   0: aload_0   #24           //  com/example/ExamplePackage$Application$05fdfa5c   1: invokestatic  #27           // Method com/example/ExamplePackage$Application$05fdfa5c.main:([Ljava/lang/String;)V

so that is why :findMainClass gets confused.

Now, I’m wondering: why are these two methods generated at all? Why do we have more than one main() method?


PS: the problem can be easily fixed by adding the following lines inside build.gradle

springBoot {   mainClass = '_DefaultPackage' }

or, in the case of the com.example package:

springBoot {   mainClass = 'com.example.ExamplePackage' }


There is another way to do it, using the main class at package level

Check this example, is based on Kotlin M8 (before platformStatic support)



This is probably closer to the thing that you want to achieve