Messages sent by Spring JmsTemplate not being received by normal JCSMP subscriber
I am able to successfully send and receive topic messages via Spring JMS but the messages are not being received by a normal Topic subscriber.
My jms code for sending and receiving is below:
@Autowired private JmsTemplate jmsTemplate; public void run(String... strings) throws Exception { for( int i = 0 ; i < 100; i++) { String msg = "Hello World" + i; jmsTemplate.setPubSubDomain(true); //jmsTemplate.setdu logger.info("============= Sending " + msg); this.jmsTemplate.convertAndSend("abc/topic2", msg); Thread.sleep(1000); } } } @Component static class MessageHandler { private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class); @JmsListener(destination = "abc/topic2", containerFactory = "cFactory", concurrency = "2") public void processMsg(Message<?> msg) { // Works fine, no issues. StringBuffer msgAsStr = new StringBuffer("============= Received \nHeaders:"); MessageHeaders hdrs = msg.getHeaders(); msgAsStr.append("\nUUID: "+hdrs.getId()); msgAsStr.append("\nTimestamp: "+hdrs.getTimestamp()); Iterator<String> keyIter = hdrs.keySet().iterator(); while (keyIter.hasNext()) { String key = keyIter.next(); msgAsStr.append("\n"+key+": "+hdrs.get(key)); } msgAsStr.append("\nPayload: "+msg.getPayload()); logger.info(msgAsStr.toString()); } public CachingConnectionFactory producerCachingConnectionFactory() throws Exception { CachingConnectionFactory ccf = new CachingConnectionFactory(connectionFactory()); ccf.setSessionCacheSize(1); return ccf; } @Bean public JmsTemplate jmsTemplate() throws Exception { // CachingConnectionFactory ccf = new CachingConnectionFactory(cf); JmsTemplate jsmTemplate = new JmsTemplate(producerCachingConnectionFactory() ); jsmTemplate.setPubSubDomain(true); jsmTemplate.setDeliveryPersistent(false); // tried both true and false. //jsmTemplate.setSessionTransacted(true); // I get an exception ... isnt supported with Direct transport. return jsmTemplate; }
@Bean
public ConnectionFactory connectionFactory() throws Exception {
Hashtable<String, Object> env = new Hashtable<>(); env.put(InitialContext.PROVIDER_URL, jndiProviderURL); env.put(Context.SECURITY_PRINCIPAL, username); env.put(Context.SECURITY_CREDENTIALS, password); System.setProperty("java.security.krb5.conf", KRB5_LOC); System.setProperty("java.security.auth.login.config", JAAS_LOC); env.put(SupportedProperty.SOLACE_JMS_AUTHENTICATION_SCHEME, SupportedProperty.AUTHENTICATION_SCHEME_GSS_KRB); env.put(SupportedProperty.SOLACE_JMS_KRB_SERVICE_NAME, "HOST"); env.put(SupportedProperty.SOLACE_JMS_VPN, vpn); env.put(SupportedProperty.SOLACE_JMS_DYNAMIC_DURABLES, false); env.put(SupportedProperty.SOLACE_JMS_DELIVER_TO_ONE_OVERRIDE , false); SolConnectionFactory cf = SolJmsUtility.createConnectionFactory(env ); return cf; } @Bean public DefaultJmsListenerContainerFactory cFactory(ConnectionFactory connectionFactory, DemoErrorHandler errorHandler) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setErrorHandler(errorHandler); factory.setPubSubDomain(true); factory.setSubscriptionDurable(false); return factory; }
I wonder if you can spot some obvious issue here please?
Many Thanks,
Ali
Comments
-
Hi Ali,
To clarify a few things:- The MessageHandler in the code you're sharing is indeed receiving and processing the message?
- Your other receiver, not in the post, is just the TopicSubscriber.java class as is with only a change to the
TOPIC_NAME
variable? - Can you share the rest of your class above where you autowire the jmstemplate?
thanks,
Marc0 -
Attempt No2 for a reply... pls find my answers inline.
@marc said:
Hi Ali,
To clarify a few things:- The MessageHandler in the code you're sharing is indeed receiving and processing the message?
Yes that is correct.
- Your other receiver, not in the post, is just the TopicSubscriber.java class as is with only a change to the
TOPIC_NAME
variable?
Yap, code is below which is tried and tested as its part of a gui tool we use for testing on daily basis.
private void subscribeSolaceTopic(String pTopic) { try { solaceConsumer = solaceSession.getMessageConsumer(new XMLMessageListener() { public void onReceive(BytesXMLMessage msg) { LOG.info("onReceive->Message Dump: {}", msg.dump()); }); } public void onException(JCSMPException e) { LOG.error("Consumer received exception: {}", e); } }); Topic topic = JCSMPFactory.onlyInstance().createTopic(pTopic); solaceTopic = topic; solaceSession.addSubscription(topic); LOG.info("Connected. Awaiting message..."); solaceConsumer.start(); } catch (JCSMPException e1) { LOG.error(EXCEPTION_OCCURRED , e1); } }
- Can you share the rest of your class above where you autowire the jmstemplate?
The autowire is done on a field and its up there near the top of my first post. If you want I can try attaching the entire project ?
Thanks,
Ali0 -
Hey Marc,
The receiver is basically a gui that was throwing exceptions behind the scenes because it was receiving wrong type of message.
java.lang.ClassCastException: com.solacesystems.jcsmp.impl.XMLContentMessageImpl cannot be cast to
com.solacesystems.jcsmp.BytesMessageTo remedy this we are now using
jmsTemplate.convertAndSend("abc/topic2", msg.getBytes()); // instead of just msg which is a String
Apologies for the red herring post.
Thanks,
Ali0