Weld SE shut down by shutdown hook doesn't executes @PreDestroy

1k views Asked by At

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...

1

There are 1 answers

2
bambula On

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 simple System.out.println("preDestroy"); then it appears in the console as a charm.