Для некоторого контекста я выполняю чтение и запись 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, чтобы этого не происходило, или, возможно, управлять им после завершения чтения, чтобы заставить его правильно закрыться.