1

I have added ShutDownHook to my Spring Boot Application. When I pass SIGTERM to my application, shutdown hook got triggered but it is terminated in halfway i.e, in middle of execution. Googled it and tried many solutions it is not working. Some expert, please help me on this.

Main Class:

ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(MyApp.class)
            .profiles("default")
            .registerShutdownHook(false)
            .build()
            .run(args);
    Runtime.getRuntime().addShutdownHook(new Thread(new GracefulShutdownHook(applicationContext)));

GracefulShutdownHook Class:

public class GracefulShutdownHook implements Runnable {
    private final ConfigurableApplicationContext applicationContext;

    public GracefulShutdownHook(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void run() {
        try {
            log.info("Gonna wait for 5 seconds before shutdown SpringContext!");
            Thread.sleep(5 * 1000);
            log.info("Spring Application context starting to shutdown");
            applicationContext.close();
            log.info("Spring Application context is shutdown");
        } catch (InterruptedException e) {
            log.error("Error while gracefulshutdown Thread.sleep", e);
        }
    }
}

I want shutdown hook to update some cache and also some logic which consumes some extra processing time.

Log when I try to kill using 'kill -15':

Apr 13 10:08:22 ssed java[14354]: 2018-04-13T10:08:22,778 INFO  [c.o.GracefulShutdownHook] -- Gonna wait for 10 seconds before shutdown SpringContext!

I am using embedded Jetty server. I have also enabled Jetty log but only above log getting printed while shutdown. My expectation is applicationContext.close() should be called after 10 sec sleep but thread is not resuming after 10 sec.

Please find the below log when I try to stop using systemctl.

Apr 12 15:24:51 vm33 systemd[1]: Stopping Session Application Service...
Apr 12 15:24:51 vm33 java[29538]: 2018-04-12T15:24:51,421 INFO  [c.o.GracefulShutdownHook] -- Gonna wait for 10 seconds before shutdown SpringContext!
Apr 12 15:25:01 vm33 systemd[1]: Stopped Session Application Service.

I developed one simple basic java program with shutdown hook and try to interrupt using 'kill -15'. The shutdown hook is working fine perfectly.

Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86
Raashith
  • 155
  • 3
  • 16
  • Can you please share the logs – Vinay Prajapati Apr 13 '18 at 12:56
  • How do you know it is "terminated in halfway"? Are you getting any error messages or exceptions? Please [edit] your question to include the exact error messages including any stacktrace. – Kenster Apr 13 '18 at 12:57
  • See if https://stackoverflow.com/questions/26678208/spring-boot-shutdown-hook post helps you. – Vinay Prajapati Apr 13 '18 at 12:58
  • Why are you registering your own? The default shutdown hook does exactly the same? Also you are registering the shutdown hook AFTEr the application has (or is) shut down assuming you are using a web application that is. – M. Deinum Apr 13 '18 at 12:59
  • @M.Deinum I want shutdown hook to update some cache and also some logic which consumes some extra processing time. So I need shutdown hook. – Raashith Apr 14 '18 at 06:22
  • @VinayPrajapati & Kenster I have added the logs. – Raashith Apr 14 '18 at 06:49
  • Why would you need a shutdown hook? A `DisposableBean` or `@PreDestroy` annotated method inside a component would work as well. But as stated you are registering your shutdown hook too late the application is already shutting down, next to that a shutdown hook isn't a guarantee as it is done based on a best effort. – M. Deinum Apr 16 '18 at 05:15
  • DisposableBean is bean level event right ? I want to pause my complete application for few seconds. Is it possible ? – Raashith Apr 16 '18 at 06:23
  • I have removed shutdown and added both ContextClosedEvent listener & @PreDestroy. But program got terminated even before ContextClosedEvent was executed fully. – Raashith Apr 16 '18 at 07:37
  • Found out the reason. Logger was shutdown while my shutdown hook is in progress. My shutdown hook was executing fully but only logs are not getting printed. – Raashith Apr 16 '18 at 10:02
  • Hi, did you find a solution? I want to the do something similar but same behavior as you got. – Shehan Simen Feb 26 '20 at 05:39
  • @ShehanSimen As I mentioned in previous reply, Logger was shutdown while my shutdown hook is in progress. My shutdown hook was executing fully but only logs are not getting printed. we can disable log4j shutdown hook using -Dlog4j.shutdownHookEnabled=false – Raashith Jun 19 '20 at 13:35

1 Answers1

0

you can add this code to do things when shutdown:

@RestController
@Slf4j
public class GetDataController {

  //your code

  @PreDestroy
  public void onExit() {
    log.info("###STOPing controller ##");
    try {
      Thread.sleep(5 * 1000);
    } catch (InterruptedException e) {
      log.error("", e);;
    }
    log.info("###STOP FROM THE LIFECYCLE controller###");
  }
}

@RestController may be other like @Component@SpringBootApplication and so on.

lizhipeng
  • 661
  • 7
  • 6