Skip to content

added sample usage of ActiveMQ Topic (use both Queue and Topic in same app) #6356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Arnaud-Nauwynck
Copy link

I found it non-intuitive to subscribe both to a Topic and a Queue in single spring-boot / springframework application.

The following code seems OK, but does not work

@Component 
public class MyJmsListener {
  @JmsListener(destination = "TestQueue1") 
  public void receiveQueueMsg(String msg) {}

  @JmsListener(destination = "TestTopic1") 
  public void receiveTopicMsg(String msg) {}
}

so I have enhanced the sample "spring-boot-samples/spring-boot-sample-activemq" to make it work
Basically, you have to be explicit to use a bean configuration "jmsListenerContainerTopic" ...

@JmsListener(destination = "TestTopic1", containerFactory="jmsListenerContainerTopic")

  • I have signed the CLA

Sorry, something went wrong.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 8, 2016
@snicoll
Copy link
Member

snicoll commented Jul 8, 2016

Thank you for the PR but that's a lot of code for a sample. For one the Consumer must be as simple as possible and it's not the case anymore. I don't really understand the two configuration for queues and topics (you shouldn't change the broker according to that).

If you find this confusing, how about improving the doc? Probably in Spring Framework then but if you submit a PR here, I am more than happy to review it as well.

@snicoll snicoll closed this Jul 8, 2016
@snicoll snicoll added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 8, 2016
@Arnaud-Nauwynck
Copy link
Author

basically, I have discovered that you can either subscribe to Queue or to a
Topic, but NOT both when using default provided conf in spring-boot.
The usage of spring-boot is therefore counter intuitive.

  • subscribe to a Queue is OK (when using default
    application.properties spring.jms.pub-sub-domain=false)
  • or subscribe to Topic when overriding application.properties
    spring.jms.pub-sub-domain=true

Internally, it is because spring-boot create a default autoconfigured
JmsListenerContainerFactory bean and choose pubSubDomain=true/false based
on application.properties file, but you would need 2 differents beans for
subscribing to both Queues and Topics.
Spring-boot is able to start your application context, and you think
everything is ok (you have no error / no log) , but in fact you are not
receiveing any JMS event ! I have lost 2 hours trying to debug it, and I
am sure I am not the only one.
This is why I say spring-boot @EnableAutoconfigure is counter intuitive
for JMS config : you still have to define your
JmsListenerContainerFactory explicitely, and if you don't, you have only
50% chance that it works for your case.

This was not really the case when using springframework directly, because
you had to define a JmsListenerContainerFactory bean explicitely otherwise
your app would not start , which draw your attention to the problem of
choosing field value pubSubDomain=true/false.

Of course, it is true that it might be much simpler if springframework was
able to auto-detect how to subscribe using pubSubDomain=false for Queues
and pubSubDomain=true for Topics, using a single JmsListenerContainerFactory

Regards,

Arnaud

2016-07-08 10:07 GMT+02:00 Stéphane Nicoll notifications@github.com:

Thank you for the PR but that's a lot of code for a sample. For one the
Consumer must be as simple as possible and it's not the case anymore. I
don't really understand the two configuration for queues and topics (you
shouldn't change the broker according to that).

If you find this confusing, how about improving the doc? Probably in
Spring Framework then but if you submit a PR here, I am more than happy to
review it.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#6356 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAtAti-BY-yMpZMebUJrHvsCmjexJYMMks5qTgU3gaJpZM4JHy-k
.

@snicoll
Copy link
Member

snicoll commented Jul 10, 2016

@Arnaud-Nauwynck something puzzles me in your description. ActiveMQ creates JMS destinations on the fly for you so if you have a setup with a destination named foo it's going to create a Queue named foo for you by default and both the receiving and sending will work (though you intended a Topic). If you let ActiveMQ does its thing, you are facing unexpected side effects...

I have lost 2 hours trying to debug it

If you have a listener on a destination and that destination doesn't exist, you'll get a big stacktrace in the logs. If you have a setup that works differently, please share it (that would be a spring framework issue by the way).

Also DestinationResolver can be tuned. If you want to create a DestinationResolver that identifies prefixes, you can do so. Name your queue queue/myQueue and your topic topic/myTopic and have the destination resolver remove the prefix and translate the destination type for you. With Spring Boot, define a DestinationResolver bean and we'll detect it for both the container factory and the template.

@Arnaud-Nauwynck
Copy link
Author

for my tests, I started ActiveMQ, and connected to the web admin page, then
created both the queue and topic.
It was not created "on-the-fly" by ActiveMQ client.

2016-07-10 11:33 GMT+02:00 Stéphane Nicoll notifications@github.com:

@Arnaud-Nauwynck https://github.com/Arnaud-Nauwynck something puzzles
me in your description. ActiveMQ creates JMS destinations on the fly for
you so if you have a setup with a destination named foo it's going to
create a Queue named foo for you by default and both the receiving and
sending will work (though you intended a Topic). If you let ActiveMQ does
its thing, you are facing unexpected side effects...

I have lost 2 hours trying to debug it

If you have a listener on a destination and that destination doesn't
exist, you'll get a big stacktrace in the logs. If you have a setup that
works differently, please share it (that would be a spring framework issue
by the way).

Also DestinationResolver can be tuned. If you want to create a
DestinationResolver that identifies prefixes, you can do so. Name your
queue queue/myQueue and your topic topic/myTopic and have the destination
resolver remove the prefix and translate the destination type for you. With
Spring Boot, define a DestinationResolver bean and we'll detect it for
both the container factory and the template.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#6356 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAtAtnuHqmPCyjD-7OiUw003bxCuXRhbks5qULxegaJpZM4JHy-k
.

@happyangellxq
Copy link

Do you have already solved the problem, I also met the same problem.

@Arnaud-Nauwynck
Copy link
Author

I have forked it, and made a pull request but the example was too long and the pull request was closed.
#6356

basically, you have to use 2 distinct JmsListenerContainerFactory wether you listen to a Queue or to a Topic

        @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerTopic() {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setPubSubDomain(true);
        bean.setConnectionFactory(activeMQConnectionFactory);
        return bean;
    }

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerQueue() {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setConnectionFactory(activeMQConnectionFactory);
        return bean;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants