How to Shut Down a Spring Boot Command-Line Application

How to shut down a Spring Boot command-line application

The answer depends on what it is that is still doing work. You can probably find out with a thread dump (eg using jstack). But if it is anything that was started by Spring you should be able to use ConfigurableApplicationContext.close() to stop the app in your main() method (or in the CommandLineRunner).

Programmatically shut down Spring Boot application

Closing a SpringApplication basically means closing the underlying ApplicationContext. The SpringApplication#run(String...) method gives you that ApplicationContext as a ConfigurableApplicationContext. You can then close() it yourself.

For example,

@SpringBootApplication
public class Example {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
// ...determine it's time to shut down...
ctx.close();
}
}

Alternatively, you can use the static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...) helper method to do it for you. For example,

@SpringBootApplication
public class Example {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
// ...determine it's time to stop...
int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
// no errors
return 0;
}
});

// or shortened to
// int exitCode = SpringApplication.exit(ctx, () -> 0);

System.exit(exitCode);
}
}

How to stop a spring boot service from command line?

If you have Spring Boot Actuator included in your project, you can enable a shutdown endpoint (by default it is not enabled). This means that if you make a request to: http://yourserver.com/yourapp/shutdown, the application will shutdown gracefully. An administrator could do such a request using a standard tool such as curl.

See Endpoints in the Spring Boot reference documentation. You can enable the shutdown endpoint by adding the following to your application.properties:

endpoints.shutdown.enabled=true

Ofcourse, you'll want to restrict access to this endpoint, otherwise anyone who has access to the service could do a request and shutdown the application.

Force a Spring Boot application to exit when there's an exception

It was not too difficult.. but not obvious either. I fixed it by catching the exception and forcing to exit in the finally block :

@SpringBootApplication
@Slf4j
public class EmailKpiTrackerApplication implements CommandLineRunner {

private final EmailKpiTracker emailKpiTracker;

private final ConfigurableApplicationContext context;

public EmailKpiTrackerApplication(EmailKpiTracker emailKpiTracker, ConfigurableApplicationContext context) {

this.emailKpiTracker = emailKpiTracker;
this.context=context;
}

public static void main(String[] args) {
SpringApplication.run(EmailKpiTrackerApplication.class, args).close();
}

@Override
public void run(String... args) throws Exception {
try {
emailKpiTracker.recordNewProcessedEmails();
}
catch(Exception e){
log.error("problem running the application",e);
}
finally {
System.exit(SpringApplication.exit(context));
}
}
}

how to close the application during startup in spring boot

We have a lot of options to shutdown spring-boot application:

Shutdown rest endpoint - add below properites to your application.properties and fire following request curl -X POST localhost:port/actuator/shutdown

management.endpoints.web.exposure.include=*  
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true

Also you can call suitable method to shutdown application:

  • By calling method close() on ConfigurableApplicationContext object (it will close application context)
  • By passing exit code to method SpringApplication.exit(ctx, () -> 0);

Please check this article for more details.

Spring boot return exit code for CommandLine app

There is a nice article answering your question on https://www.baeldung.com/spring-boot-exit-codes. Here is the gist:

@SpringBootApplication
public class CLI implements CommandLineRunner, ExitCodeGenerator {

private int exitCode; // initialized with 0

public static void main(String... args) {
System.exit(SpringApplication.exit(SpringApplication.run(CLI.class, args)));
}

/**
* This is overridden from CommandLineRunner
*/
@Override
public void run(String... args) {
// Do what you have to do, but don't call System.exit in your code
this.exitCode = 1;
}

/**
* This is overridden from ExitCodeGenerator
*/
@Override
public int getExitCode() {
return this.exitCode;
}
}


Related Topics



Leave a reply



Submit