英文:
Exception while trying to consume a JMS Topic message using Spring Boot
问题
以下是翻译好的部分:
我正在尝试从ActiveMQ主题中消费消息。以下是代码:
@Configuration
@EnableJms
public class Config {
@Value("${activemq.broker-url}")
private String brokerURL;
@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(brokerURL);
activeMQConnectionFactory.setTrustAllPackages(true);
return activeMQConnectionFactory;
}
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
defaultJmsListenerContainerFactory.setPubSubDomain(true);
return defaultJmsListenerContainerFactory;
}
}
我的消费者代码:
@Component
@EnableJms
public class Consumer {
@JmsListener(destination = "xml.inbound.topic", containerFactory = "jmsListenerContainerFactory")
public void Processor(final Message xmlMessage) {
}
}
我得到的异常是:
Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jms.core.JmsTemplate]: Factory method 'jmsTemplate' threw exception; nested exception is java.lang.ClassCastException: class org.springframework.jms.config.DefaultJmsListenerContainerFactory cannot be cast to class javax.jms.ConnectionFactory (org.springframework.jms.config.DefaultJmsListenerContainerFactory and javax.jms.ConnectionFactory are in unnamed module of loader 'app')
我在这里做错了什么?为什么会出现异常?
我还尝试过:
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setConnectionFactory(activeMQConnectionFactory());
dmlc.setPubSubDomain(true);
return dmlc;
}
我在这里得到的异常是:
Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jms.core.JmsTemplate]: Factory method 'jmsTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsListenerContainerFactory' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'destination' or 'destinationName' is required
只是补充一下,我的JmsTemplate代码看起来像这样:
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
我使用Apache Camel实现了JMS主题发布者(代码):
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
CamelContext _ctx = new DefaultCamelContext();
_ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
_ctx.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
from("file:src/main/resources?fileName=data-sample_2.csv")
.process(new MyTransformRevised1())
.to("file:src/main/resources/?fileName=emp.xml")
.split(body().tokenizeXML("equityFeeds", null)).streaming().to("jms:topic:xml.inbound.topic");
}
});
我能够在主题名称的“消息入队”列中看到消息数。
发生了什么错误?我已经阅读了网络上的各种帖子,但无法解决这个问题。请帮助解决这个问题。我无法在ActiveMQ主题上读取消息。如果我漏掉了一些信息,请告诉我。
英文:
I am trying to consume message from ActiveMQ Topic. Below is the Code:
@Configuration
@EnableJms
public class Config {
@Value("${activemq.broker-url}")
private String brokerURL;
@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(brokerURL);
activeMQConnectionFactory.setTrustAllPackages(true);
return activeMQConnectionFactory;
}
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
defaultJmsListenerContainerFactory.setPubSubDomain(true);
return defaultJmsListenerContainerFactory;
}
My Consumer Code:
@Component
@EnableJms
public class Consumer {
@JmsListener(destination = "xml.inbound.topic", containerFactory = "jmsListenerContainerFactory")
public void Processor(final Message xmlMessage) {
}
}
The Exception which I am getting is:
Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jms.core.JmsTemplate]: Factory method 'jmsTemplate' threw exception; nested exception is java.lang.ClassCastException: class org.springframework.jms.config.DefaultJmsListenerContainerFactory cannot be cast to class javax.jms.ConnectionFactory (org.springframework.jms.config.DefaultJmsListenerContainerFactory and javax.jms.ConnectionFactory are in unnamed module of loader 'app')
What am I doing wrong here ? Why the exception?
I have also tried :
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setConnectionFactory(activeMQConnectionFactory());
dmlc.setPubSubDomain(true);
return dmlc;
}
The Exception which I get here is:
Unsatisfied dependency expressed through field 'jmsTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsTemplate' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jms.core.JmsTemplate]: Factory method 'jmsTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jmsListenerContainerFactory' defined in class path resource [com/investmentbank/equityfeedsprocessingrevised/config/Config.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'destination' or 'destinationName' is required
Just to add my JmsTemplate code looks like this:
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
I have implemented the JMS Topic Publisher using Apache Camel (Code):
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
CamelContext _ctx = new DefaultCamelContext();
_ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
_ctx.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
from("file:src/main/resources?fileName=data-sample_2.csv")
.process(new MyTransformRevised1())
.to("file:src/main/resources/?fileName=emp.xml")
.split(body().tokenizeXML("equityFeeds", null)).streaming().to("jms:topic:xml.inbound.topic");
}
});
I am able to see the number of messages in "Message Enqueued" column of my Topic name.
What is going wrong ? I have read various posts on net but not able to solve the issue. Kindly help in resolving the issue. I am not able to read the message on ActiveMQ Topic. Let me know if some information is missing from my end.
答案1
得分: 2
你可以尝试将`activeMQConnectionFactory`包装在`CachingConnectionFactory`中,并利用`DefaultJmsListenerContainerFactoryConfigurer`来配置`JmsListenerContainerFactory`:
@Bean
ConnectionFactory connectionFactory() {
return new CachingConnectionFactory(activeMQConnectionFactory());
}
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
EDIT start:
你可以尝试将`JmsTemplate`更改为:
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory);
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
英文:
you could try to wrap the activeMQConnectionFactory
in a CachingConnectionFactory
and utilize the DefaultJmsListenerContainerFactoryConfigurer
to configure the JmsListenerContainerFactory
:
@Bean
ConnectionFactory connectionFactory() {
return new CachingConnectionFactory(activeMQConnectionFactory());
}
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
EDIT start:
could you try changing the JmsTemplate
to:
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory);
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
答案2
得分: 0
我用以下代码解决了这个问题:
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
defaultJmsListenerContainerFactory.setPubSubDomain(true);
return defaultJmsListenerContainerFactory;
}
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
@JmsListener(destination = "${my.inboundTopicName}", containerFactory = "jmsListenerContainerFactory")
public void myProcessor(final Message xmlMessage) {
///
}
我想补充说明,我遇到了一些异常行为。
-
在生产者生成消息的同时,如果消费者正在运行,那么消费者只会消费到消息。也就是说,如果消息由生产者生成并由ActiveMQ排队,然后过了一段时间我启动消费者,那么消费者将无法消费到这些消息。
-
此外,消费者消费消息之前需要一些时间。
英文:
I solved this with the below Code:
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
defaultJmsListenerContainerFactory.setPubSubDomain(true);
return defaultJmsListenerContainerFactory;
}
@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
jmsTemplate.setPubSubDomain(true);
return jmsTemplate;
}
@JmsListener(destination = "${my.inboundTopicName}", containerFactory = "jmsListenerContainerFactory")
public void myProcessor(final Message xmlMessage) {
///
}
I want to add that I am experiencing some unusual behavior.
-
At the time when the messages are generated from the producer and if
the consumer is up then only the messages are consumed by the
consumer. I mean that if the messages are produced by the producer
and enqueued by ActiveMQ and after some time I turn on the consumer
then the messages are not consumed by the consumer. -
. Also it takes a while before the messages are consumed by the
consumer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论