Weld SE, отключенный хуком выключения, не выполняет @PreDestroy

У меня есть очень простое приложение Java Weld SE. Согласно документам, Weld регистрирует, чтобы правильно отключить контейнеры. Я ожидаю, что он попытается правильно закрыть все управляемые компоненты, но вместо этого кажется, что контейнер немедленно завершает работу.

Простой компонент CDI:

@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);
        }
    }
}

И главное:

public class Main {
    public static void main(String[] args) {
        Weld weld = new Weld();
        WeldContainer container = weld.beanClasses(CDIBean.class)
                .disableDiscovery().initialize();
    }
}

вывод консоли (приложение закончилось на CTRL+C или kill -15, оба имеют одинаковый результат):

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

Но если контейнер выключается программно с помощью container.close(), завершение работает нормально:

.
.
.
INFO: Still running...
INFO: Still running...
INFO: preDestroy
INFO: WELD-ENV-002001: Weld SE container 999543ef-ae42-4617-8536-329412f3a9c7 shut down

Итак, мой вопрос: как корректно завершить работу контейнера при получении SIGTERM? Встроенный хук выключения этого не делает...


person bambula    schedule 06.12.2019    source источник


Ответы (1)


Ну-ну-ну - не Weld, а logger сбил меня с толку. Встроенный обработчик завершения работы работает, как и ожидалось, но регистратор перестает заходить в консоль после получения SIGTERM. Поэтому, если я изменю тело метода @PreDestroy на простое System.out.println("preDestroy");, оно появится в консоли как чудо-кнопка.

person bambula    schedule 06.12.2019