JMSListener selector not working
Asked Answered
C

1

2

I have a JMS producer sending 2 kinds of messages: business logic and heart beat messages. Currently, both are handled by the same receiver, but I am now trying to have dedicated classes for each by using selectors. The problem I have is whenever I add the selector to the receiver, it stops receiving messages. Here is what I have so far. For simplicity, I have only added the code for the heart beat:

To send the message, I have this:

private void sendHeartBeat() {
    this.buildTemplate().send(new HeartbeatMessageCreator(this.someId));
}

private JmsTemplate buildTemplate() {
    if (this.cachedJmsTemplate == null) {
        final ActiveMQTopic activeMQTopic = new ActiveMQTopic(this.topic);
        this.cachedJmsTemplate = new JmsTemplate(this.config.getCachedConnectionFactory());
        this.cachedJmsTemplate.setDefaultDestination(activeMQTopic);
        this.cachedJmsTemplate.setPubSubDomain(true);
    }
    return this.cachedJmsTemplate;
}

HeartbeatMessageCreator:

class HeartbeatMessageCreator implements MessageCreator {
private final String someID;

HeartbeatMessageCreator(final String someID) {
    this.someID = someID;
}

@Override
public Message createMessage(final Session session) throws JMSException {
    final Serializable message = new ZHeartBeat(this.someID);
    final Message jmsMessage = session.createObjectMessage(message);
    jmsMessage.setJMSType(message.getClass().getName());
    jmsMessage.setStringProperty("InternalMessageType", "HeartBeat"); // <-- Setting my separator here

    return jmsMessage;
}

The consumer is as follow:

@Component
public class MyListener {

    @JmsListener(destination = "${myTopic}", containerFactory = "myJmsContainer", selector = "InternalMessageType = 'HeartBeat'")
    public final void onMessage(final Message message) {

    ...

    }
}

In this configuration, the consumer never sees the messages coming in, but if I remove the selector part from the @JmsListener annotation, they are delivered. I am not sure what I am doing wrong here. Any idea ?

Cuvette answered 27/9, 2017 at 16:56 Comment(0)
A
5

It works fine for me...

@SpringBootApplication
public class So46453364Application implements CommandLineRunner {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext ctx = SpringApplication.run(So46453364Application.class, args);
        Thread.sleep(10_000);
        ctx.close();
    }

    @Autowired
    private JmsTemplate template;

    @Override
    public void run(String... arg0) throws Exception {
        this.template.convertAndSend("foo", "foo", m -> {
            m.setStringProperty("foo", "bar");
            return m;
        });
        this.template.convertAndSend("foo", "foo", m -> {
            m.setStringProperty("foo", "baz");
            return m;
        });
    }

    @JmsListener(destination = "foo", selector = "foo = 'bar'")
    public void bar(Message in) {
        System.out.println("bar: " + in);
    }

    @JmsListener(destination = "foo", selector = "foo = 'baz'")
    public void baz(Message in) {
        System.out.println("baz: " + in);
    }

}

result

bar: ActiveMQTextMessage {commandId = 5, responseRequired = true, messageId = ID:gollum.local-53472-1506533911909-4:3:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:gollum.local-53472-1506533911909-4:3:1:1, destination = queue://foo, transactionId = null, expiration = 0, timestamp = 1506533912140, arrival = 0, brokerInTime = 1506533912141, brokerOutTime = 1506533912144, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 1030, properties = {foo=bar}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = foo}
baz: ActiveMQTextMessage {commandId = 5, responseRequired = true, messageId = ID:gollum.local-53472-1506533911909-4:4:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:gollum.local-53472-1506533911909-4:4:1:1, destination = queue://foo, transactionId = null, expiration = 0, timestamp = 1506533912150, arrival = 0, brokerInTime = 1506533912150, brokerOutTime = 1506533912150, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 1030, properties = {foo=baz}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = foo}
Alenealenson answered 27/9, 2017 at 17:41 Comment(1)
You are absolutely right. I found the problem in my case: there was a component sitting between the producer and consumer, which was supposed to simply forward the messages. But the way it was done meant that the message properties were not reaching the final destination. Thx for your time.Cuvette

© 2022 - 2024 — McMap. All rights reserved.