Below is the sample code , i.e
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
log.info("Starting...");
mainThread.start();
mainThread.join();
log.info("Exiting...");
}
@EventListener
public void onApplicationEvent(ContextClosedEvent event) {
log.info("Inside on ApplicationEvent");
mainThread.interrupt();
log.info("Thread Interupted");
}
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
}
}
}
- someAppLogic.doLogic(); get called in mainThread on Spring Boot Application start
- The goal is to have mainThread interrupt in the method on ApplicationEvent in case of exception in the someAppLogic.doLogic(); and have an exitcode as 1.
But the issue is main.interrupt() inside onApplicationEvent never gets called in case of exception from the run method i.e when someAppLogic.doLogic() throws an exception.
This Spring boot application is going to be deployed in Kubernetes so pod containing this should gracefully shutdown .
SO the question is How to handle any exception thrown by someAppLogic.doLogic(); gracefully and send exitcode as 1 ?
CodePudding user response:
You need to invoke close() on ConfigurableApplicationContext for ContextClosedEvent to be published.
//you need to figure out how to get hold of this object
private ConfigurableApplicationContext context;
@Override
public void run() {
try {
someAppLogic.doLogic();
} catch (Exception e) {
if (e instanceof InterruptedException || e.getCause() instanceof InterruptedException) {
log.info("Interrupted...");
} else {
log.error("Exception occurred", e);
exitCode = 1;
//call close
context.close();
}
}
}