активный mq и spring jmstemplate, как правильно завершить работу

Для некоторого контекста я выполняю чтение и запись JMS в пакете Spring, используя реализацию, совместимую с jsr. Я использую классы записи JMSReader и JMS, предоставляемые пакетом Spring, но я оборачиваю их в свои собственные программы чтения и записи. У меня нет доступного типичного контекста приложения, так как я использую подход JSR. Классы инициализируются через спецификацию задания или через пакетный файл.xml в соответствии со спецификацией jsr.

Проблема, с которой я столкнулся, заключается в том, что у меня есть отдельное пакетное приложение, которое, когда я определяю средство чтения JMS и/или средство записи jms, которое создает фабрику соединений для активного mq и устанавливает ее в качестве целевой фабрики для класса Spring JMSTemplate, приложение после завершения обработка не останавливается должным образом. Альтернатива с использованием фабрики соединений для IBM MQ работает нормально.

Позвольте мне предоставить код, который я сделал.

Здесь я создаю свою фабрику соединений. Есть пара прокомментированных строк изменений, которые я внес, пытаясь заставить потоки, оставшиеся в живых, умереть вместе с приложением.

private ConnectionFactory openAMQ() throws IllegalArgumentException{
    ActiveMQConnectionFactory targetConnectionFactory = new ActiveMQConnectionFactory();

    if(protocol == null){
        throw new IllegalArgumentException("Active MQ protocol can not be empty");
    }

    AMQProtocols proto = AMQProtocols.valueOf(protocol.toUpperCase());

    StringBuilder sb = new StringBuilder();

    sb.append(proto.getProtocol()).append("://").append(this.host).append(":").append(this.port);

    if(amqParams != null && amqParams.trim().length() > 0){
        sb.append("?").append(amqParams);
    }

    targetConnectionFactory.setBrokerURL(sb.toString());
    //targetConnectionFactory.setAlwaysSessionAsync(false);
    //targetConnectionFactory.setUseAsyncSend(false);
    return targetConnectionFactory;
}

Здесь я создаю объект JMSTemplate

protected JmsTemplate getJMSTemplate(ConnectionFactory targetConnectionFactory){
    CachingConnectionFactory ccf = new CachingConnectionFactory();

    ccf.setTargetConnectionFactory(targetConnectionFactory);
    JmsTemplate template = new JmsTemplate(ccf);

    template.setDefaultDestinationName(jmsDefaultDestinationName);

    template.setReceiveTimeout(Long.parseLong(jmsReceiveTimeoutValue));
    template.setSessionTransacted(Boolean.parseBoolean(jmsSessionTransacted));
    //template.setMessageConverter(messageConverter);


    return template;
}

И, наконец, открытый метод JMSReader, писатель почти идентичен

public void open(Serializable checkpoint) throws Exception {

    //First we need to get our broker specific connection factory
    ConnectionFactory targetConnectionFactory = getTargetConnectionFactory();

    this.template = getJMSTemplate(targetConnectionFactory);

    reader = new JmsItemReader();
    reader.setItemType(Class.forName(jmsItemTypeFullyQualifiedName));
    reader.setJmsTemplate(template);

}

Потоки, которые я вижу живыми, похоже, связаны с соединением, а также с некоторыми потоками мониторинга бездействия. Благодаря тому, что они остаются в живых, это предотвращает закрытие отдельного приложения.

Кто-нибудь знает, как я могу настроить фабрику соединений или шаблон jms, чтобы этого не происходило, или, возможно, управлять им после завершения чтения, чтобы заставить его правильно закрыться.


person Mark Kouba    schedule 22.10.2015    source источник


Ответы (1)


Думаю, я ответил на свой вопрос. В CachingConnectionFactory я добавил вызов метода destroy в методе close как чтения, так и записи jms. У меня есть некоторые опасения, что вызов, который не позволяет выполнить надлежащую очистку, но позволяет приложению закрываться, а не зависать.

person Mark Kouba    schedule 23.10.2015