Reputation: 41750
I have some @Scheduled
events in my app and I was wondering how can I determine whether a request to shut down the Spring boot app was triggered so I don't bother doing extra work?
That is I want to avoid errors like this e.g.
java.lang.IllegalStateException: Shutdown in progress
at java.base/java.lang.ApplicationShutdownHooks.add(ApplicationShutdownHooks.java:66) ~[na:na]
at java.base/java.lang.Runtime.addShutdownHook(Runtime.java:214) ~[na:na]
at org.xbill.DNS.NioClient.selector(NioClient.java:57) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.NioUdpClient.sendrecv(NioUdpClient.java:158) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.SimpleResolver.sendAsync(SimpleResolver.java:371) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.SimpleResolver.sendAsync(SimpleResolver.java:338) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.lookup.LookupSession.lookupWithResolver(LookupSession.java:477) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.lookup.LookupSession.lambda$lookupWithCache$6(LookupSession.java:472) ~[dnsjava-3.5.0.jar:na]
at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
at org.xbill.DNS.lookup.LookupSession.lookupWithCache(LookupSession.java:472) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.lookup.LookupSession.lookupUntilSuccess(LookupSession.java:448) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.lookup.LookupSession.lookupAsync(LookupSession.java:385) ~[dnsjava-3.5.0.jar:na]
at org.xbill.DNS.lookup.LookupSession.lookupAsync(LookupSession.java:367) ~[dnsjava-3.5.0.jar:na]
at net.trajano.swarm.gateway.discovery.Util.getIpAddresses(Util.java:93) ~[classes/:na]
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273) ~[na:na]
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312) ~[na:na]
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
at net.trajano.swarm.gateway.discovery.DockerServiceInstanceLister.refresh(DockerServiceInstanceLister.java:77) ~[classes/:na]
at net.trajano.swarm.gateway.discovery.DockerEventWatcher$DockerEventWatcherEventCallback.onNext(DockerEventWatcher.java:81) ~[classes/:na]
at net.trajano.swarm.gateway.discovery.DockerEventWatcher$DockerEventWatcherEventCallback.onNext(DockerEventWatcher.java:49) ~[classes/:na]
at com.github.dockerjava.core.exec.AbstrAsyncDockerCmdExec$1.onNext(AbstrAsyncDockerCmdExec.java:41) ~[docker-java-core-3.2.13.jar:na]
at com.github.dockerjava.core.DefaultInvocationBuilder$JsonSink.accept(DefaultInvocationBuilder.java:315) ~[docker-java-core-3.2.13.jar:na]
at com.github.dockerjava.core.DefaultInvocationBuilder$JsonSink.accept(DefaultInvocationBuilder.java:298) ~[docker-java-core-3.2.13.jar:na]
at com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:275) ~[docker-java-core-3.2.13.jar:na]
at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]
Upvotes: 0
Views: 1914
Reputation: 50
As you might have noticed, it has a problem of duplicating a status. So it has been fixed, and you can autowire ConfigurableApplicationContext
and use boolean isClosed()
to achieve your goal very easily.
Upvotes: 0
Reputation: 2026
You can catch the ContextClosedEvent:
...
import org.springframework.context.event.ContextClosedEvent;
...
@RestController
public class Application {
...
boolean isShuttingDown = false;
...
@EventListener({ ContextClosedEvent.class })
public void onApplicationEvent(ContextClosedEvent event) {
isShuttingDown = true;
}
...
}
Upvotes: 3