I have a very simple Java Weld SE application. According to docs the Weld registers a should hook to shutdown the containers properly. I would expect it tries to shutdown all managed beans properly, but instead it seems the container finishes immediately.
Simple CDI bean:
@ApplicationScoped
public class CDIBean {
private static final Logger logger = Logger.getLogger(CDIBean.class.getName());
private AtomicBoolean keepRunning;
private CountDownLatch threadFinished;
public void start(@Observes ContainerInitialized event) {
logger.log(Level.INFO, "start");
}
@PostConstruct
public void postConstruct() {
logger.log(Level.INFO, "postConstruct");
keepRunning = new AtomicBoolean(true);
threadFinished = new CountDownLatch(1);
new Thread(() -> {
while (keepRunning.get()) {
try {
logger.log(Level.INFO, "Still running...");
Thread.sleep(200);
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}
threadFinished.countDown();;
}).start();
}
@PreDestroy
public void preDestroy() {
logger.log(Level.INFO, "preDestroy");
keepRunning.set(false);
try {
threadFinished.await();
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}
}
And main:
public class Main {
public static void main(String[] args) {
Weld weld = new Weld();
WeldContainer container = weld.beanClasses(CDIBean.class)
.disableDiscovery().initialize();
}
}
the console output (app ended by CTRL+C
or kill -15
, both have the same result):
INFO: WELD-000900: 3.1.3 (Final)
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
INFO: WELD-ENV-002003: Weld SE container 07a30136-de8f-47f9-ad5f-fbdf85cc5b60 initialized
INFO: postConstruct
INFO: start
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
INFO: Still running...
^CWeld SE container 07a30136-de8f-47f9-ad5f-fbdf85cc5b60 shut down by shutdown hook
But if the container is shutdown programatically using container.close()
the termination works fine:
.
.
.
INFO: Still running...
INFO: Still running...
INFO: preDestroy
INFO: WELD-ENV-002001: Weld SE container 999543ef-ae42-4617-8536-329412f3a9c7 shut down
So my question is: how to make the container shutdown gracefully when SIGTERM
is received? The built-in shutdown hook doesn't do that...
Well, well, well - not Weld but logger made me to be confused. The built-in shutdown hook works as expected, but the logger stops logging into console after the
SIGTERM
is received. So if I change the body of @PreDestroy method to simpleSystem.out.println("preDestroy");
then it appears in the console as a charm.