Sometimes we may want to create command line applications using Spring Boot. Spring Boot has org.springframework.boot.CommandLineRunner interface to represent this. However, it's possible that the application may continue running even after the main method exits. This is because some Spring components may have non-daemon threads running, e.g. Spring JDBC or Cassandra threads. This post shows how to exit the application after the main task is finished.

Below is a simple task to run.

@Component
class TaskRunner {
    fun run() {
        println("Run task")
    }
}

In the code below, CommandLineApplication is the Spring Boot application that implements CommandLineRunner. In the run method, TaskRunner is invoked. After TaskRunner.run() returns, SpringApplication.exit is invoked to close Spring's application context, which will exit the application.

@SpringBootApplication
class CommandLineApplication(
    private val applicationContext: ApplicationContext,
    private val taskRunner: TaskRunner
) : CommandLineRunner {

    override fun run(vararg args: String?) {
        taskRunner.run()
        SpringApplication.exit(applicationContext)
    }

}

fun main(args: Array<String>) {
    runApplication<CommandLineApplication>(*args)
}

By doing this, you can make sure that the application will exit correctly.