Announcement Announcement Module
Collapse
No announcement yet.
Using JMS as exposed Service Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using JMS as exposed Service

    Hi,

    I'm evaluating how to properly send data to a remote Websphere MQ Queue by using Spring 3.2.1.
    Prerequisites:
    - I want to access this WMQ Queue by using JMS with JNDI names to not depend directly on IBM WMQ libraries.
    - I want to use javaconfig and not XML configuration.
    I'm using JBoss EAP 6.0.1. the JNDI names are defined in the standalone.xml "MQConnectionFactory" is a "connection-definition" and "MQQueue" is an "admin-object".

    At first I tried to use JMSTemplate:

    Code:
    @Configuration
    public class JmsMonitoringConfiguration {
    
    	@Bean
    	public JmsTemplate jmsTemplate() throws NamingException {
    		JndiObjectFactoryBean connection = new JndiObjectFactoryBean();
    		connection.setJndiName("java:/MQConnectionFactory");
    		connection.afterPropertiesSet();
    
    		JndiObjectFactoryBean destination = new JndiObjectFactoryBean();
    		destination.setJndiName("java:/MQQueue");
    		destination.afterPropertiesSet();
    
    		JmsTemplate jmsTemplate = new JmsTemplate();
    		jmsTemplate.setConnectionFactory((ConnectionFactory) connection.getObject());
    		jmsTemplate.setDefaultDestination((Destination) destination.getObject());
    		jmsTemplate.setReceiveTimeout(20000);
    		jmsTemplate.afterPropertiesSet();
    		return jmsTemplate;
    
    	}
    }
    My example-Java-Code to utilize this bean is:

    Code:
    @Component
    public class TestResource {
    	@Inject
    	JmsTemplate jmsTemplate;
    
    	public test() {
    
    		jmsTemplate.send(new MessageCreator() {
    			@Override
    			public Message createMessage(Session session) throws JMSException {
    				return session.createTextMessage("hello queue world");
    			}
    		});
    
    	}
    }
    This seems to work without any notable problems.


    I now discovered JmsInvokerProxyFactoryBean and this sounds even better than JMSTemplate and I decided to use this:

    Code:
    @Configuration
    public class JmsMonitoringServiceConfiguration {
    
    	@Bean
    	public ISender sender() throws NamingException {
    
    		JndiObjectFactoryBean connection = new JndiObjectFactoryBean();
    		connection.setJndiName("java:/MQConnectionFactory");
    		connection.afterPropertiesSet();
    
    		JmsInvokerProxyFactoryBean invokerProxy = new JmsInvokerProxyFactoryBean();
    		invokerProxy.setServiceInterface(IMonitoringSender.class);
    		invokerProxy.setConnectionFactory((ConnectionFactory) connection.getObject());
    		invokerProxy.setDestinationResolver(new JndiDestinationResolver());
    		invokerProxy.setQueueName("java:/MQQueue");
    		//invokerProxy.setReceiveTimeout(20000);
    
    		invokerProxy.afterPropertiesSet();
    
    		return (ISender) invokerProxy.getObject();
    	}
    }
    The interface definition is:

    Code:
    public interface ISender {
    	public void sendData(String daten);
    }
    My Test-Code is:

    Code:
    @Component
    public class TestResource {
    	@Inject
    	ISender sender;
    
    	public test() {
    
    		sender.sendData("23");
    
    	}
    }
    Now the execution waits in JmsInvokerClientInterceptor Line 366 and does not continue.

    Code:
    			return (timeout > 0 ? consumer.receive(timeout) : consumer.receive());
    The JNDI Lookups seem to work perfectly fine for both lookups as I inspected the Objects in JmsInvokerClientInterceptor.executeRequest.
    When I set a RecieveTimeout and re-execute the test-code the timeout is reached and I'm now getting an exception instead of a not-ending-java process:

    Code:
    15:21:59,144 ERROR [....MiddlewareExceptionMapper] (http-localhost/127.0.0.1:8080-1) Could not access JMS invoker queue [java:/MQQueue]; nested exception is javax.jms.MessageFormatException: Invalid response message: null: org.springframework.remoting.RemoteAccessException: Could not access JMS invoker queue [java:/MQQueue]; nested exception is javax.jms.MessageFormatException: Invalid response message: null
    	at org.springframework.jms.remoting.JmsInvokerClientInterceptor.convertJmsInvokerAccessException(JmsInvokerClientInterceptor.java:431) [org.springframework.jms-3.2.1.RELEASE.jar:3.2.1.RELEASE]
    	at org.springframework.jms.remoting.JmsInvokerClientInterceptor.invoke(JmsInvokerClientInterceptor.java:204) [org.springframework.jms-3.2.1.RELEASE.jar:3.2.1.RELEASE]
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) [org.springframework.aop-3.2.1.RELEASE.jar:3.2.1.RELEASE]
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) [org.springframework.aop-3.2.1.RELEASE.jar:3.2.1.RELEASE]
    Greetings, OlliL

  • #2
    It depends on your use case... Do you want to send a message or do you want to a RPC over JMS.

    The first (using JmsTemplate) simply puts a message on a queue and you can opt for waiting for a reply.

    The latter is basically a RPC over JMS and it expects that on the server side there is a service exposed by the JmsInvokerServiceExporter which exposes a service with the same interface.

    Judging from the snippets of code my guess is you want to do ther first simply send data if so use a JmsTemplate. A small tip instead of the send method use the convertAndSend method saves you the inner class.

    Code:
    jmsTemplate.convertAndSend("hello queue world");

    Comment


    • #3
      Oh dear... I re-read the documentation and it looks like I got it wrong in the first place.
      The whole topic seems to be about accessing a remote "Service" via JMS transparently. And I thought I can use JmsInvokerProxyFactoryBean to send data to a "generic MQ Queue" - this seems to not be the case

      Edit:
      @Marten
      - I want a "put and forget about it" mechanism as the receiving side of the queue is a completly different application with no feeding back. I guess this will only be possible with a JmsTemplate?
      - At one point I need a BytesMessage() to be transfered. Can convertAndSend handle this? It is important that on the MQ layer a BytesMessage arrives as this triggers a different handling on MQ side and the message looks different than a generic ObjectMessage or TextMessage.
      Last edited by OlliL; Jun 3rd, 2013, 10:12 AM.

      Comment

      Working...
      X